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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
struct Peg
{
private struct Disk
{
private int size;
picture draw(pen p = pink+1mm)
{
picture pic;
fill(pic, scale(5mm+size*7.5mm, 4mm)*box((-1/2,-1/2),(1/2,1/2)), p);
label(pic, string(size));
return pic;
}
void operator init(int size)
{
this.size = size;
}
}
private Disk[] disks;
private string name;
string getname()
{
return name;
}
picture draw(pen p = blue+1mm)
{
picture pic;
int n = disks.length;
fill(pic, box((-2mm, -4mm),(2mm,40mm)), gray);
fill(pic, box((-4cm, -10mm), (4cm, -4mm)), gray);
label(pic, name, (0,-5mm), align=down);
for (int k = 0; k < n; ++k)
add(pic, disks[k].draw(), (0,k*5mm));
return pic;
}
void operator init(int n, string name)
{
for (int k = n; k > 0; --k)
disks.push(Disk(k));
this.name = name;
}
static void transfer(Peg a, Peg b)
{
Disk disk = a.disks.pop();
b.disks.push(disk);
}
}
from Peg unravel transfer;
import animation;
//usepackage("animate");
//usepackage("movie15");
settings.tex = "pdflatex";
void solvehanoi(int n)
{
animation ani;
int step = 0;
Peg A = Peg(n,"A"), B = Peg(0,"B"), C = Peg(0,"C");
picture pic;
add(pic, A.draw().fit(), 0, align=NW);
add(pic, B.draw().fit(), 0, align=NE);
add(pic, C.draw().fit(), 0, align=S);
ani.add(pic);
void solve(Peg src, Peg dest, Peg mid, int k)
{
if (k != 0) {
solve(src, mid, dest, k-1);
transfer(src, dest);
++step;
write(format("%3d: ", step)
+ src.getname() + " -> " + dest.getname());
picture pic;
add(pic, A.draw().fit(), 0, align=NW);
add(pic, B.draw().fit(), 0, align=NE);
add(pic, C.draw().fit(), 0, align=S);
ani.add(pic);
solve(mid, dest, src, k-1);
}
}
solve(A, B, C, n);
//label(ani.pdf(delay=500));
ani.movie(delay=500);
}
solvehanoi(2);
|