Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

Re: Recursion: the Towers of Hanoi problem

by tachyon (Chancellor)
on Oct 19, 2004 at 03:34 UTC ( #400400=note: print w/replies, xml ) Need Help??

in reply to Recursion: The Towers of Hanoi problem

As always there are non recursive solutions. This one is 14 lines long if you exclude the animation code.

#!/usr/bin/perl -w print "Number of disks? "; chomp( my $numdisks = <STDIN> ); print "Sleep? "; chomp( my $sleep = <STDIN> ); $numdisks ||= 8; $sleep ||= 0.1; my $board = [ [], [], [], [] ]; push @{$board->[1]}, $_ for reverse 1 .. $numdisks; my %tower = map{ my $str =' 'x($numdisks-$_).'o'x$_; $str = $str.($_?'+':'|').reverse($str); $_, " $str " } 0..$numdisks; hanoi( $numdisks ); sub hanoi { my $n = shift; my $n1 = $n+1; my @D = (1)x$n1; my @s = 1..$n1+1; my $dir = 1 & $n; for(;;) { my $i = $s[0]; do{ show($n,0,0,1); last } if $i>$n; my $to =($D[$i]+($i&1?$dir:1-$dir))%3+1; show( $i, $D[$i], $to ); $D[$i] = $to; $s[0] = 1; $s[$i-1] = $s[$i]; $s[$i] = $i+1; } } sub show { my ( $num, $from, $to, $show_final ) = @_; $^O =~ m/Win32/ ? system("cls") : system("clear"); for my $i( reverse 0..$numdisks ) { print "\n", map{$tower{ $board->[$_]->[$i] || 0} }1..3; } return if $show_final; push @{$board->[$to]}, pop @{$board->[$from]}; print "\n\nMove disk $num from $from to $to\n"; select undef, undef, undef, $sleep; }



Replies are listed 'Best First'.
Re^2: Recursion: the Towers of Hanoi problem
by pg (Canon) on Oct 19, 2004 at 04:07 UTC

    To be fair, you didn't win today ;-)

    Yesterday, you gave a non-recursive version of the number guessing game. You won, as in that case, there was absolutely no need for recursion, other than for fun.

    But in the case of Towers of Hanoi, the recursive version is way more beautiful than the non-recursive version. I am not talking about the fact that your code is longer than the recursive version, although that is one of those little things...

    Th real winning point is that: in the recursive version, you don't think or coding, but simply tell the computer that: to make this move, you have to make those two moves first. That's it, that's all what you need to tell the computer. The rest is not your business any more:

    sub movedisks { #to make this move
    my( $num, $from, $to, $aux ) = @_; if( $num == 1 ) { ; } else {
    #you have to make those two moves first movedisks( $num-1, $from, $aux, $to ); movedisks( $num-1, $aux, $to, $from );
    } }

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://400400]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (11)
As of 2017-10-20 11:20 GMT
Find Nodes?
    Voting Booth?
    My fridge is mostly full of:

    Results (261 votes). Check out past polls.