use strict; use Benchmark::Timer; my $T = new Benchmark::Timer; no warnings 'recursion'; my($Ack,$Fib,$Tak); $Ack = sub { my ($x, $y) = @_; return $y + 1 if $x == 0; return $Ack->($x - 1, 1) if $y == 0; $Ack->($x - 1, $Ack->($x, $y - 1)); }; sub Ack { my( $x, $y ) = @_; my @stack; push @stack, $x; do { $x = pop @stack; if( $x == 0 ) { ++$y; } elsif( $y == 0 ) { push @stack, $x - 1; $y = 1; } else { push @stack, $x - 1, $x; --$y; } } while @stack; return $y; } my $n = ($ARGV[0] || 0) - 1; $T->start( 'Recursive Ack 3,' . ( $n+1 ) ); printf "Ack(%d,%d): %d\n", 3, $n + 1, $Ack->(3, $n + 1); $T->stop( 'Recursive Ack 3,' . ( $n+1 ) ); $T->start( 'Iterative Ack 3,' . ( $n+1 ) ); printf "Ack(%d,%d): %d\n", 3, $n + 1, Ack( 3, $n + 1 ); $T->stop( 'Iterative Ack 3,' . ( $n+1 ) ); $T->report;