sub hanoi { my ($n, $a, $b, $c) = @_; return if $n < 1; hanoi($n-1, $a, $c, $b); print "Moving plate from $a to $b\n"; return hanoi($n-1, $c, $b, $a); } -- Example of call $ hanoi(8, "A", "B", "C") => 2^8 - 1 moves -- Comment $n is the number of plates (> 0) to move from pole A to pole B using auxiliary pole C The final 'return' allows for a slight tail-call optimization #### ## # hanoi n a b c # Without recursivity nor goto. # Franck PORCHER use constant log_2 => log(2); sub hanoi { my ($n, $a, $b, $c) = @_; my $p = 1; my $k; do { if ( $n ) { $p <<= $n; ($b, $c) = ($c, $b) if ($n & 1); $n = 0; } if ( ($p - 1) && ( $p & 1) ){ $k = log(($p ^ ($p + 1)) & ($p + 1)) / log_2; $p >>= $k; ($a, $b) = ($b, $a) if ($k & 1); $n += $k; $p ||= 1; } if ( $p - 1 ) { print "Moving plate from $a to $b\n"; ($a, $b, $c) = ($c, $a, $b); $p++; } } while $p - 1; } -- Example of call $ hanoi(8, "A", "B", "C") => 2^8 - 1 moves