All Classes Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
generator.hpp
1 // The MIT License (MIT)
2 
3 // Copyright (c) 2012-2014 Rapptz
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 // this software and associated documentation files (the "Software"), to deal in
7 // the Software without restriction, including without limitation the rights to
8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 // the Software, and to permit persons to whom the Software is furnished to do so,
10 // subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22 #ifndef GEARS_MATH_GENERATOR_HPP
23 #define GEARS_MATH_GENERATOR_HPP
24 
25 #include <vector>
26 #include <iterator>
27 #include <cmath>
28 #include "algorithm.hpp"
29 
30 namespace gears {
31 namespace math {
46 template<typename Container, typename Value = typename Container::value_type>
47 inline void primes(Value limit, Container& cont) {
48  cont.push_back(2);
49  cont.push_back(3);
50 
51  Value offset = limit % 6 > 1;
52  Value wheels[6] = { limit, limit - 1, limit + 4, limit + 3, limit + 2, limit + 1 };
53  Value k = 0;
54  Value n = wheels[limit % 6];
55  std::vector<bool> sieve(n / 3, true);
56  sieve[0] = false;
57  for(Value i = 0, upper = static_cast<Value>(std::sqrt(n))/3; i <= upper; ++i) {
58  if(sieve[i]) {
59  k = (3 * i + 1) | 1;
60  for(Value j = (k * k) / 3; j < n / 3; j += 2 * k) {
61  sieve[j] = false;
62  }
63 
64  for(Value j = (k * k + 4 * k - 2 * k * (i & 1)) / 3; j < n / 3; j += 2 * k) {
65  sieve[j] = false;
66  }
67  }
68  }
69 
70  for(Value i = 1; i < n / 3 - offset; ++i) {
71  if(sieve[i]) {
72  cont.push_back((3 * i + 1) | 1);
73  }
74  }
75 }
76 
91 template<typename Container, typename Integral>
92 inline void pythagorean_triples(Integral limit, Container& cont) {
93  for(Integral i = 1; i < limit; ++i) {
94  if((i * i + (i + 1) * (i + 1)) > limit) {
95  break;
96  }
97 
98  for(Integral j = i + 1; j < limit; j += 2) {
99  if(j * j + i * i > limit) {
100  break;
101  }
102 
103  if(gcd(i, j) > 1) {
104  continue;
105  }
106 
107  cont.emplace_back(j * j - i * i, 2 * i * j, i * i + j * j);
108  }
109  }
110 }
111 } // math
112 } // gears
113 
114 #endif // GEARS_MATH_GENERATOR_HPP