diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2019-07-18 18:47:38 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-07-18 18:47:38 +0100 |
| commit | bae3ca3afea6371976cc6e2da9a591eb4a4bd95e (patch) | |
| tree | 58c33773e01ea05d42c4983cb87ff54633511ff5 | |
| parent | ebe0f790ee9d7f029f24785160ba12a826612ddf (diff) | |
| parent | e2e7c76c65c5b341cf15926ca4f5600949250aa1 (diff) | |
| download | perlweeklychallenge-club-bae3ca3afea6371976cc6e2da9a591eb4a4bd95e.tar.gz perlweeklychallenge-club-bae3ca3afea6371976cc6e2da9a591eb4a4bd95e.tar.bz2 perlweeklychallenge-club-bae3ca3afea6371976cc6e2da9a591eb4a4bd95e.zip | |
Merge pull request #388 from myrrhlin/pyrrhlin-pwc
Pyrrhlin pwc
| -rw-r--r-- | challenge-015/michael-hamlin/README | 6 | ||||
| -rw-r--r-- | challenge-017/michael-hamlin/README | 4 | ||||
| l--------- | challenge-017/michael-hamlin/perl5/ch-1.pl | 1 | ||||
| -rw-r--r-- | challenge-017/michael-hamlin/perl5/t1-ackermann-simple.pl | 35 | ||||
| -rw-r--r-- | challenge-017/michael-hamlin/perl5/t1-ackermann-two.pl | 84 |
5 files changed, 130 insertions, 0 deletions
diff --git a/challenge-015/michael-hamlin/README b/challenge-015/michael-hamlin/README index 4314e219f4..c5737036e7 100644 --- a/challenge-015/michael-hamlin/README +++ b/challenge-015/michael-hamlin/README @@ -1 +1,7 @@ Solutions by Michael Hamlin. + + +Notes: + +* the Vigenere encoder/decoder supports multiple keys +* don't forget that modular operator `%` does not do what you want with negative integers! diff --git a/challenge-017/michael-hamlin/README b/challenge-017/michael-hamlin/README index 4314e219f4..3c1a735306 100644 --- a/challenge-017/michael-hamlin/README +++ b/challenge-017/michael-hamlin/README @@ -1 +1,5 @@ Solutions by Michael Hamlin. + +ch-1.pl the Ackermann function grows so rapidly that I dont think I can +test the real hyperness of my code, even with GMP. + diff --git a/challenge-017/michael-hamlin/perl5/ch-1.pl b/challenge-017/michael-hamlin/perl5/ch-1.pl new file mode 120000 index 0000000000..bc89ccf6fc --- /dev/null +++ b/challenge-017/michael-hamlin/perl5/ch-1.pl @@ -0,0 +1 @@ +t1-ackermann-two.pl
\ No newline at end of file diff --git a/challenge-017/michael-hamlin/perl5/t1-ackermann-simple.pl b/challenge-017/michael-hamlin/perl5/t1-ackermann-simple.pl new file mode 100644 index 0000000000..406fe6073e --- /dev/null +++ b/challenge-017/michael-hamlin/perl5/t1-ackermann-simple.pl @@ -0,0 +1,35 @@ +#! /usr/bin/env perl +# + +use 5.22.0; +use warnings; +use feature 'signatures'; +no warnings 'experimental::signatures'; +use integer; + +# really need the big integers when $m >= 4 +# use bigint lib => 'GMP'; + +no warnings 'recursion'; + +my $count = 0; + +sub _ack( $m, $n ) { + state @known; + $count++; + return $known[$m][$n] ||= do { + !$m ? $n + 1 : + !$n ? _ack($m - 1, 1) : + _ack($m - 1, _ack($m, $n - 1)); + }; +} +sub ack ( $m, $n ) { + die "the function is not defined for negative parameters" if $m < 0 || $n < 0; + return _ack($m, $n); +} + +die "must give two nonnegative integers as input" unless @ARGV > 1; + +$" = ', '; +say "A( @ARGV ) = ", ack(@ARGV), " ...after $count calls."; + diff --git a/challenge-017/michael-hamlin/perl5/t1-ackermann-two.pl b/challenge-017/michael-hamlin/perl5/t1-ackermann-two.pl new file mode 100644 index 0000000000..bdb6ce5e2a --- /dev/null +++ b/challenge-017/michael-hamlin/perl5/t1-ackermann-two.pl @@ -0,0 +1,84 @@ +#! /usr/bin/env perl +# + +use 5.22.0; +use warnings; +use feature 'signatures'; +no warnings 'experimental::signatures'; + +# really need the big integers when $m >= 4 +# unfortunately the function grows so quickly even this doesnt help a lot +use bigint lib => 'GMP'; + +my $trace = 0; +my %limits = ( + 5 => 0, + 4 => 2, +); + +# the hyper function, H_$n($a, $b), with $a = 2: +sub _twohyper( $n, $b ) { + my $result = 2; + if ($n == 0) { + $result = $b + 1; + } elsif ($b == 0) { + # shortcut this? but never happens in our problem + $result = $n == 1 ? 2 : + $n == 2 ? 0 : 1; + } elsif ($n == 1) { + $result += $b; + } elsif ($n == 2) { + $result *= $b; + } elsif ($b == 0) { + $result = 1; + } elsif ($b == 1) { + # result is just 2 + } elsif ($n == 3) { + # exponentiation is iterated multiplication + $result = 1 << $b; # 2 ** $b + } elsif ($n == 4) { + # tetration is iterated exponentiation + for (2 .. $b) { $result = 1 << $result } # 2 ** $result + } else { + # $n > 4 means iterated hyper... + $result = _twohyper( $n - 1, 2 ); + if ($b > 2) { + for (3 .. $b) { $result = _twohyper( $n - 1, $result ) } + } + } + say "2hyper( $n, $b ) = ", $result if $trace; + return $result; +} +sub ack2 ( $m, $n ) { + die "the function is not defined for negative parameters" if $m < 0 || $n < 0; + if (defined my $nlimit = $limits{$m}) { + warn "this may run out of memory..." if $n > $nlimit; + } + return _twohyper($m, $n + 3) - 3; +} + +unless (@ARGV) { + _test(); + exit(0); +} +die "must give two nonnegative integers as input" unless @ARGV > 1; + +$" = ', '; +my $result = ack2(@ARGV); +my $desc = $result->length < 78 ? $result : + sprintf 'int with %u digits', length($result); +say "A( @ARGV ) = ", $desc; + + +sub _test { + for my $m (0 .. 5) { + my $nlimit = $limits{$m} // 5; + for my $n (0 .. $nlimit) { + my $result = ack2($m, $n); + my $desc = $result->length < 78 ? $result : + sprintf 'int with %u digits', length($result); + say "A( $m, $n ) = ", $desc; + } + } +} + |
