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);