Project Euler problem

This is a discussion on Project Euler problem within the C++ Programming forums, part of the General Programming Boards category; hi all, I haven't touched c++ in a while. I'm just doing it in today to solve a problem in ...

  1. #1
    -bleh-
    Join Date
    Aug 2010
    Location
    somewhere in this universe
    Posts
    452

    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?
    Last edited by nimitzhunter; 04-15-2012 at 04:12 PM.
    "All that we see or seem
    Is but a dream within a dream." - Poe

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    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.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    -bleh-
    Join Date
    Aug 2010
    Location
    somewhere in this universe
    Posts
    452
    Quote Originally Posted by oogabooga View Post
    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.
    "All that we see or seem
    Is but a dream within a dream." - Poe

  4. #4
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    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>
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  5. #5
    -bleh-
    Join Date
    Aug 2010
    Location
    somewhere in this universe
    Posts
    452
    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.
    "All that we see or seem
    Is but a dream within a dream." - Poe

  6. #6
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    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);
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  7. #7
    -bleh-
    Join Date
    Aug 2010
    Location
    somewhere in this universe
    Posts
    452
    Yeah, that's the solution. Thanks for your help, oogabooga.
    "All that we see or seem
    Is but a dream within a dream." - Poe

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Project Euler Problem 8
    By deadrabbit in forum C Programming
    Replies: 2
    Last Post: 10-06-2011, 10:56 PM
  2. Project Euler
    By CodeGuru25 in forum C Programming
    Replies: 2
    Last Post: 01-13-2010, 05:25 AM
  3. Project Euler Problem 14 Segfault
    By vincent01910 in forum C Programming
    Replies: 5
    Last Post: 11-04-2009, 04:56 AM
  4. Project Euler problem 3
    By SELFMADE in forum C Programming
    Replies: 7
    Last Post: 09-16-2009, 03:33 AM
  5. Project Euler Question
    By Head In Jar Man in forum C++ Programming
    Replies: 6
    Last Post: 04-26-2009, 02:59 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21