Skip to content

Commit 12edee9

Browse files
committed
Meta-hanoi using templates
1 parent 8423f1e commit 12edee9

File tree

1 file changed

+37
-17
lines changed

1 file changed

+37
-17
lines changed

metahanoi.cpp

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,47 @@ constexpr tower getTower(state s, size disk) {
2121
: getTower(s / 3, disk - 1);
2222
}
2323

24-
constexpr state solve(size disks, state s, tower target) {
25-
return disks == 0
26-
? s
27-
: getTower(s, disks) == target
28-
? solve(disks - 1, s, target)
29-
: solve(disks - 1,
30-
move(solve(disks - 1,
31-
s,
32-
other(getTower(s, disks), target)),
33-
getTower(s, disks),
34-
target),
35-
target);
36-
}
37-
3824
std::ostream &print_state(std::ostream &os, size ndisks, state s) {
3925
return ndisks ? print_state(os, ndisks - 1, s / 3) << s % 3 : os;
4026
}
4127

28+
template <size DISKS, state S, tower SRC, tower TARGET>
29+
struct SolverRec {
30+
static constexpr tower nextSrc = getTower(S, DISKS - 1);
31+
static constexpr tower inter = other(SRC, TARGET);
32+
using rec1 = SolverRec<DISKS - 1, S, nextSrc, inter>;
33+
static constexpr state value = move(rec1::final_state, SRC, TARGET);
34+
using rec2 = SolverRec<DISKS - 1, value, inter, TARGET>;
35+
static constexpr state final_state = rec2::final_state;
36+
};
37+
38+
template <size DISKS, state S, tower TOWER>
39+
struct SolverRec<DISKS, S, TOWER, TOWER> {
40+
static constexpr tower nextSrc = getTower(S, DISKS - 1);
41+
using rec = SolverRec<DISKS - 1, S, nextSrc, TOWER>;
42+
static constexpr state final_state = rec::final_state;
43+
};
44+
45+
template <state S, tower SRC, tower TARGET>
46+
struct SolverRec<1, S, SRC, TARGET> {
47+
static constexpr state final_state = move(S, SRC, TARGET);
48+
};
49+
50+
template <state S, tower TOWER>
51+
struct SolverRec<1, S, TOWER, TOWER> {
52+
static constexpr state final_state = S;
53+
};
54+
55+
template <size DISKS, state S, tower TARGET>
56+
struct Solver {
57+
static constexpr tower src = getTower(S, DISKS);
58+
using start = SolverRec<DISKS, S, src, TARGET>;
59+
static constexpr state final_state = start::final_state;
60+
};
61+
4262
int main() {
43-
constexpr int disks = 5;
44-
constexpr state result = solve(disks, 0, 2);
45-
print_state(std::cout, disks, result) << std::endl;
63+
constexpr size disks = 5;
64+
using solver = Solver<disks, 0, 2>;
65+
print_state(std::cout, disks, solver::final_state) << std::endl;
4666
return 0;
4767
}

0 commit comments

Comments
 (0)