# Project Euler problem

• 04-15-2012
nimitzhunter
Project Euler problem
hi all,
I haven't touched c++ in a while. I'm just doing it in today to solve a problem in Project Euler. This is problem 42. Find a triangle word.
Code:

```#include <cmath> #include <iostream> #include <fstream> #include <vector> #include <algorithm> #include <iterator> #include <cstring> #include <iomanip> class TriangleFinder { private:   int  TriangleCount; public:   TriangleFinder():TriangleCount(0) {}   void  operator() (std::string);   int print_result() const { return TriangleCount;}; };     void TriangleFinder::operator() (std::string sInput) {   int                  value=0;   std::string::iterator it = sInput.begin();   double                root;     for ( ; it < sInput.end() ; ++it)     {       value+= (*it) -64;     }   // find out whether root is an interger.   root  = sqrt(double(value)*8+1);   if ( fabs(floor(root)-root) < 1e-6)     {       TriangleCount++;     }   /*  std::cout <<std::setw(10) << sInput             <<std::setw(10) << root             <<std::setw(10) << fabs(floor(root)-root)             <<std::setw(10) << TriangleCount << std::endl;   */ } int main() {   using namespace      std;   string                sTmp;   vector<string>        vStr;   ifstream              inFile("words.txt");   TriangleFinder        Finder;     while (getline(inFile,sTmp,','))     {       sTmp.erase(sTmp.begin());       sTmp.erase(sTmp.end()-1);       vStr.push_back(sTmp);     }   //  copy(vStr.begin(),vStr.end(),ostream_iterator<string>(cout,"\n"));   for_each(vStr.begin(),vStr.end(),Finder);   cout << Finder.print_result() << endl; }```
The problem i ran into is that
Code:

`cout << Finder.print_result() << endl;`
keep returning 0. Could someone please tell me why the member variable TriangleCount get overwrites with 0?
• 04-15-2012
oogabooga
Interesting. It's something to do with using the for_each. I'm not enough of a C++ guy to know what's wrong. If you use an explicit loop it works correctly:
Code:

```  for (vector<string>::iterator it = vStr.begin(); it != vStr.end(); ++it)       Finder(*it);```
Note that this iterator loop of yours works but is not technically correct:
Code:

```  for ( ; it < sInput.end() ; ++it)       value+= (*it) -64;```
The comparison should be it != sInput.end(). Using < works because of implementation details you are not supposed to be relying on.

And "interger" (in your comment) has an extra r.
• 04-15-2012
nimitzhunter
Quote:

Originally Posted by oogabooga
Interesting. It's something to do with using the for_each. I'm not enough of a C++ guy to know what's wrong. If you use an explicit loop it works correctly:
Code:

```  for (vector<string>::iterator it = vStr.begin(); it != vStr.end(); ++it)       Finder(*it);```
Note that this iterator loop of yours works but is not technically correct:
Code:

```  for ( ; it < sInput.end() ; ++it)       value+= (*it) -64;```
The comparison should be it != sInput.end(). Using < works because of implementation details you are not supposed to be relying on.

And "interger" (in your comment) has an extra r.

Right, thanks for pointing that out. I'll make the change to the code. It's been a while, little details like that just just escape my memory.
• 04-15-2012
oogabooga
Here's a simplified test program demonstrating the same thing. Hopefully the experts can explain it to us.
Code:

```#include <iostream> #include <vector> #include <algorithm> using namespace std; class Sum { private:     int n; public:     Sum() : n(0) {}     void operator() (int i) { n += i; cout << n << ' '; }     void print() { cout << '<' << n << ">\n"; } }; int main() {   vector<int> v;   for (int i = 1; i <= 5; i++) v.push_back(i);   Sum s1;   for (vector<int>::iterator it = v.begin(); it != v.end(); ++it) s1(*it);   s1.print();   Sum s2;   for_each(v.begin(), v.end(), s2);   s2.print(); }```
Output:
Code:

```1 3 6 10 15 <15> 1 3 6 10 15 <0>```
• 04-15-2012
nimitzhunter
Code:

```template<class InputIterator, class Function>   Function for_each(InputIterator first, InputIterator last, Function f)   {     for ( ; first!=last; ++first ) f(*first);     return f;   }```
the return f could be the reason for so much fail on my part.
• 04-15-2012
oogabooga
Yep, you figured it out. for_each makes a copy of Function, so if you don't accept the return value the copy disappears and you're left with the original object. So it should be:
Code:

`Finder = for_each(vStr.begin(),vStr.end(),Finder);`
• 04-15-2012
nimitzhunter
Yeah, that's the solution. Thanks for your help, oogabooga.