-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpe14_cpp.cpp
More file actions
66 lines (57 loc) · 1.73 KB
/
Copy pathpe14_cpp.cpp
File metadata and controls
66 lines (57 loc) · 1.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
* pe14_cpp.cpp
* Using awful templates... why not.
* This solution does not check all numbers up to 1000000 (see note at bottom).
* Author: Michael Quigley
*/
#include <iostream>
#define CHAIN_COUNT_PARAM(N) (N), ((N) % 2)
template <long n, long is_odd>
struct ChainCount;
template <long n>
struct MaxCollatz;
// The is_odd recursive case.
template <long n>
struct ChainCount<n, 1> {
enum : long { result = 1 + ChainCount<CHAIN_COUNT_PARAM(n * 3 + 1)>::result };
};
// The !is_odd recursive case.
template <long n>
struct ChainCount<n, 0> {
enum : long { result = 1 + ChainCount<CHAIN_COUNT_PARAM(n / 2)>::result };
};
// Base case specialization.
template <>
struct ChainCount<1, 1> {
enum : long { result = 0 };
};
// MaxCollatz recursive case.
template <long n>
struct MaxCollatz {
enum : long {
best_count =
MaxCollatz<n - 1>::best_count > ChainCount<CHAIN_COUNT_PARAM(n)>::result
? MaxCollatz<n - 1>::best_count
: ChainCount<CHAIN_COUNT_PARAM(n)>::result,
best_num =
MaxCollatz<n - 1>::best_count > ChainCount<CHAIN_COUNT_PARAM(n)>::result
? MaxCollatz<n - 1>::best_num
: n
};
};
// Base case specialization.
template <>
struct MaxCollatz<1> {
enum : long { best_count = 0, best_num = 1 };
};
int main() {
// NOTE: max_num isn't being set to 1000000 like in the other solutions. This
// is because even when the maximum template depth is set to a sufficiently
// high number (-ftemplate-depth-1000000), both g++ 4.9 and clang++ 3.9
// segfault.
const long max_num = 1000;
std::cout << "Resulting number is " << MaxCollatz<max_num>::best_num
<< ", max count is " << MaxCollatz<max_num>::best_count
<< std::endl;
return 0;
}