fork download
  1. /*
  2.  * Lazy generation of Pythagorean Triples
  3.  * Inspired by http://b...content-available-to-author-only...i.com/2014/04/21/getting-lazy-with-c/
  4.  * John Zwinck, 2014-04-22
  5.  *
  6.  * This demonstrates a different, perhaps more C++ish solution to lazily
  7.  * generate a sequence. This approach does no dynamic memory allocation.
  8.  * The main idea is to implement a custom forward iterator (STL compatible).
  9.  *
  10.  * Separation of concerns are handled thusly:
  11.  * 1. Generating Pythagorean Triples is done by our triple_iterator.
  12.  * 2. Printing is handled by std::ostream_iterator<>.
  13.  * 3. Limiting the number of triples generated is via std::copy_n().
  14.  *
  15.  * As in the original version, the algorithm is naive.
  16.  */
  17.  
  18. #include <algorithm>
  19. #include <iostream>
  20. #include <iterator>
  21. #include <cassert>
  22. #include <climits>
  23.  
  24. using namespace std;
  25.  
  26. struct triple
  27. {
  28. int x = 0;
  29. int y = 0;
  30. int z = 0;
  31. };
  32.  
  33. ostream& operator<<(ostream& out, const triple& value)
  34. {
  35. //another sanity check
  36. assert((value.x * value.x) + (value.y * value.y) == (value.z * value.z));
  37. return out << value.x << ", " << value.y << ", " << value.z;
  38. }
  39.  
  40. // unbounded forward iterator producing Pythagorean Triples on demand
  41. class triple_iterator : public iterator<forward_iterator_tag, triple>, triple
  42. {
  43. public:
  44. triple_iterator() { ++*this; } // initialize to the first valid triple
  45. const triple& operator*() { return *this; }
  46.  
  47. // set ourselves to the next Pythagorean Triple
  48. triple_iterator& operator++()
  49. {
  50. //checking sanity since x,y,and z are public members of this iterator
  51. assert(z < INT_MAX);
  52. assert(y <= z);
  53. assert(x <= z);
  54.  
  55. ++y;
  56.  
  57. for (;z < INT_MAX; ++z) {
  58. for (; x < z; ++x) {
  59. for (; y < z; ++y) {
  60. if (x*x + y*y == z*z) {
  61. return *this;
  62. }
  63. }
  64. y = x + 1;
  65. }
  66. x = 1;
  67. }
  68.  
  69. cerr << "Could not calculate the next Pythagorean triple..." << endl;
  70. exit(EXIT_FAILURE);
  71. }
  72. };
  73.  
  74. int main()
  75. {
  76. // write the first few Pythagorean Triples to stdout
  77. copy_n(triple_iterator(), 100, ostream_iterator<triple>(cout, "\n"));
  78. }
  79.  
Success #stdin #stdout 0s 3340KB
stdin
Standard input is empty
stdout
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