10.1. Example: The Towers of Hanoi

In this example, which is intended to give a taste of the capabilities of references, we will solve the well-known Towers of Hanoi problem. (Refer to the link to learn more about the problem.) The number of disks can be input from the command-line. The towers themselves will be represented as an array of three elements, each of which is a reference to an array.

We will use the recursive solution in which in order to move a column of $N disks, we first move the upper column with $N-1 disks and then move the bottom most disk, and then move the $N-1 disks-long column on top of it.

Here goes:

use strict;
use warnings;

my $num_disks = shift || 9;

my @towers = (
    [ reverse(1 .. $num_disks) ],  # A [ ... ] is a dynamic reference to
    [ ],                           # an array
    [ ]
    );

sub print_towers
{
    for(my $i=0 ; $i < 3 ; $i++)
    {
        print ": ";
        print join(" ", @{$towers[$i]}); # We de-reference the tower
        print "\n";
    }
    print "\n\n";
}

sub move_column
{
    my $source = shift;
    my $dest = shift;
    my $how_many = shift;

    if ($how_many == 0)
    {
        return;
    }
    # Find the third column
    my $intermediate = 0+1+2-$source-$dest;
    move_column($source, $intermediate, $how_many-1);
    # Print the current state
    print_towers();
    # Move one disk. Notice the dereferencing of the arrays
    # using @{$ref}.
    push @{$towers[$dest]}, pop(@{$towers[$source]});
    move_column($intermediate, $dest, $how_many-1);
}

# Move the entire column
move_column(0,1,$num_disks);
print_towers();

Written by Shlomi Fish