/* * Lazy generation of Pythagorean Triples * Inspired by http://b...content-available-to-author-only...i.com/2014/04/21/getting-lazy-with-c/ * John Zwinck, 2014-04-22 * * This demonstrates a different, perhaps more C++ish solution to lazily * generate a sequence. This approach does no dynamic memory allocation. * The main idea is to implement a custom forward iterator (STL compatible). * * Separation of concerns are handled thusly: * 1. Generating Pythagorean Triples is done by our triple_iterator. * 2. Printing is handled by std::ostream_iterator<>. * 3. Limiting the number of triples generated is via std::copy_n(). * * As in the original version, the algorithm is naive. */ #include <algorithm> #include <iostream> #include <iterator> #include <cassert> #include <climits> using namespace std; struct triple { int x = 0; int y = 0; int z = 0; }; ostream& operator<<(ostream& out, const triple& value) { //another sanity check assert((value.x * value.x) + (value.y * value.y) == (value.z * value.z)); return out << value.x << ", " << value.y << ", " << value.z; } // unbounded forward iterator producing Pythagorean Triples on demand class triple_iterator : public iterator<forward_iterator_tag, triple>, triple { public: triple_iterator() { ++*this; } // initialize to the first valid triple const triple& operator*() { return *this; } // set ourselves to the next Pythagorean Triple triple_iterator& operator++() { //checking sanity since x,y,and z are public members of this iterator assert(z < INT_MAX); assert(y <= z); assert(x <= z); ++y; for (;z < INT_MAX; ++z) { for (; x < z; ++x) { for (; y < z; ++y) { if (x*x + y*y == z*z) { return *this; } } y = x + 1; } x = 1; } cerr << "Could not calculate the next Pythagorean triple..." << endl; exit(EXIT_FAILURE); } }; int main() { // write the first few Pythagorean Triples to stdout copy_n(triple_iterator(), 100, ostream_iterator<triple>(cout, "\n")); }
Standard input is empty
3, 4, 5 6, 8, 10 5, 12, 13 9, 12, 15 8, 15, 17 12, 16, 20 7, 24, 25 15, 20, 25 10, 24, 26 20, 21, 29 18, 24, 30 16, 30, 34 21, 28, 35 12, 35, 37 15, 36, 39 24, 32, 40 9, 40, 41 27, 36, 45 14, 48, 50 30, 40, 50 24, 45, 51 20, 48, 52 28, 45, 53 33, 44, 55 40, 42, 58 36, 48, 60 11, 60, 61 16, 63, 65 25, 60, 65 33, 56, 65 39, 52, 65 32, 60, 68 42, 56, 70 48, 55, 73 24, 70, 74 21, 72, 75 45, 60, 75 30, 72, 78 48, 64, 80 18, 80, 82 13, 84, 85 36, 77, 85 40, 75, 85 51, 68, 85 60, 63, 87 39, 80, 89 54, 72, 90 35, 84, 91 57, 76, 95 65, 72, 97 28, 96, 100 60, 80, 100 20, 99, 101 48, 90, 102 40, 96, 104 63, 84, 105 56, 90, 106 60, 91, 109 66, 88, 110 36, 105, 111 15, 112, 113 69, 92, 115 80, 84, 116 45, 108, 117 56, 105, 119 72, 96, 120 22, 120, 122 27, 120, 123 35, 120, 125 44, 117, 125 75, 100, 125 32, 126, 130 50, 120, 130 66, 112, 130 78, 104, 130 81, 108, 135 64, 120, 136 88, 105, 137 84, 112, 140 55, 132, 143 17, 144, 145 24, 143, 145 87, 116, 145 100, 105, 145 96, 110, 146 48, 140, 148 51, 140, 149 42, 144, 150 90, 120, 150 72, 135, 153 93, 124, 155 60, 144, 156 85, 132, 157 84, 135, 159 96, 128, 160 36, 160, 164 99, 132, 165 65, 156, 169 119, 120, 169 26, 168, 170