aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2019-07-18 18:47:38 +0100
committerGitHub <noreply@github.com>2019-07-18 18:47:38 +0100
commitbae3ca3afea6371976cc6e2da9a591eb4a4bd95e (patch)
tree58c33773e01ea05d42c4983cb87ff54633511ff5
parentebe0f790ee9d7f029f24785160ba12a826612ddf (diff)
parente2e7c76c65c5b341cf15926ca4f5600949250aa1 (diff)
downloadperlweeklychallenge-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/README6
-rw-r--r--challenge-017/michael-hamlin/README4
l---------challenge-017/michael-hamlin/perl5/ch-1.pl1
-rw-r--r--challenge-017/michael-hamlin/perl5/t1-ackermann-simple.pl35
-rw-r--r--challenge-017/michael-hamlin/perl5/t1-ackermann-two.pl84
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;
+ }
+ }
+}
+