Programming performance/JCAB Cpp

From HaskellWiki
Jump to navigation Jump to search
  • Language: C++
  • Skill: Advanced. I've been using C++ with all its features for many years.
  • Time: Approx 20 minutes.
  • Notes: I did this after doing the Haskell version, so that might have affected the time. I used Visual Studio 2003 for development. I needed two iterations (same as with Haskell, but different bugs!). I get 13754.97774 just like I did with Haskell.

Code

<pre-c>

  1. include <stdio.h>
  2. include <ctype.h>
  3. include <list>


int main() {

   std::list<double> closingCosts;
   FILE* f = fopen("C:\\JCAB\\ProgrammingPerformance\\gspc.txt", "rt");
   if (f) {
       while (!feof(f)) {
           char buf[4096];
           fgets(buf, sizeof(buf), f);
           buf[sizeof(buf)-1] = 0;
           if (buf[0] != '#') {
               char* p = buf;
               while (isspace(*p)) ++p;
               while (*p && !isspace(*p)) ++p;
               while (isspace(*p)) ++p;
               while (*p && !isspace(*p)) ++p;
               while (isspace(*p)) ++p;
               while (*p && !isspace(*p)) ++p;
               while (isspace(*p)) ++p;
               while (*p && !isspace(*p)) ++p;
               while (isspace(*p)) ++p;
               while (*p && !isspace(*p)) ++p;
               while (isspace(*p)) ++p;
               while (*p && !isspace(*p)) ++p;
               while (isspace(*p)) ++p;
               closingCosts.push_front(atof(p));
           }
       }
       fclose(f);
   }
   double cash = 10000.0;
   std::list<std::pair<double, double> > shares;
   std::list<double>::const_iterator it = closingCosts.begin();
   double lastClosing = *it;
   ++it;
   std::list<double>::const_iterator const closingCostsEnd = closingCosts.end();
   for (; it != closingCostsEnd; ++it) {
       double const currentClosing = *it;
       for (std::list<std::pair<double, double> >::iterator sIt = shares.begin(); sIt != shares.end();) {
           if (currentClosing - sIt->first >= 0.06 * sIt->first) {
               // Sell them.
               cash += sIt->second * currentClosing;
               sIt = shares.erase(sIt);
           } else {
               ++sIt;
           }
       }
       if (lastClosing - currentClosing > 0.03 * lastClosing) {
           // Buy some.
           shares.push_back(std::make_pair(currentClosing, cash * 0.10 / currentClosing));
           cash *= 0.90;
       }
       lastClosing = currentClosing;
   }
   // Sell all that's left.
   for (std::list<std::pair<double, double> >::iterator sIt = shares.begin(); sIt != shares.end(); ++sIt) {
       cash += sIt->second * lastClosing;
   }
   printf("%f\n", cash);
   return 0;

} </pre-c>