aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-106/polettix/blog.txt1
-rw-r--r--challenge-106/polettix/blog1.txt1
-rw-r--r--challenge-106/polettix/perl/ch-1.pl15
-rw-r--r--challenge-106/polettix/perl/ch-2.pl89
4 files changed, 106 insertions, 0 deletions
diff --git a/challenge-106/polettix/blog.txt b/challenge-106/polettix/blog.txt
new file mode 100644
index 0000000000..8cbc6ad9f6
--- /dev/null
+++ b/challenge-106/polettix/blog.txt
@@ -0,0 +1 @@
+https://github.polettix.it/ETOOBUSY/2021/03/31/pwc106-maximum-gap/
diff --git a/challenge-106/polettix/blog1.txt b/challenge-106/polettix/blog1.txt
new file mode 100644
index 0000000000..57ea870bba
--- /dev/null
+++ b/challenge-106/polettix/blog1.txt
@@ -0,0 +1 @@
+https://github.polettix.it/ETOOBUSY/2021/04/01/pwc106-decimal-string/
diff --git a/challenge-106/polettix/perl/ch-1.pl b/challenge-106/polettix/perl/ch-1.pl
new file mode 100644
index 0000000000..4c58951d69
--- /dev/null
+++ b/challenge-106/polettix/perl/ch-1.pl
@@ -0,0 +1,15 @@
+#!/usr/bin/env perl
+use 5.024;
+use warnings;
+use experimental qw< postderef signatures >;
+no warnings qw< experimental::postderef experimental::signatures >;
+use List::Util 'max';
+
+sub maximum_gap (@N) {
+ return 0 if @N <= 1;
+ (my $p, @N) = sort { $a <=> $b } @N;
+ return max(map { (my $d, $p) = ($_ - $p, $_); $d } @N);
+}
+
+my @input = @ARGV ? @ARGV : (1, 3, 8, 2, 0);
+say maximum_gap(@input);
diff --git a/challenge-106/polettix/perl/ch-2.pl b/challenge-106/polettix/perl/ch-2.pl
new file mode 100644
index 0000000000..94ce878c09
--- /dev/null
+++ b/challenge-106/polettix/perl/ch-2.pl
@@ -0,0 +1,89 @@
+#!/usr/bin/env perl
+use 5.024;
+use warnings;
+use experimental qw< postderef signatures >;
+no warnings qw< experimental::postderef experimental::signatures >;
+
+sub decimal_string ($N, $D) {
+ my $sign = ($N < 0) ^ ($D < 0) ? '-' : '';
+ for ($N, $D) { $_ = -$_ if $_ < 0 }
+
+ my $r = $N % $D;
+ (my $i, $N) = (($N - $r) / $D, $r);
+ $i = $sign . $i if $i || $N;
+ return $i unless $N;
+
+ # keep track of all quotes and rests we find in the integer divisions
+ my (@ds, %position_of);
+ while ($N) {
+ if (exists $position_of{$N}) {
+ push @ds, '(', splice(@ds, $position_of{$N}), ')';
+ last;
+ }
+ $position_of{$N} = @ds;
+ $N *= 10;
+ $r = $N % $D;
+ (my $i, $N) = (($N - $r) / $D, $r);
+ push @ds, $i;
+ }
+ return $i . '.' . join '', @ds;
+}
+
+sub rational_pair ($x) {
+ require Math::BigInt;
+ my ($s, $i, $d) = $x =~ m{\A (-?) (\d*) (?:\. (.*))? \z}mxs;
+ $d //= '';
+ my ($ap, $p) = $d =~ m{\A (\d*) (?: \( (\d+) \) )?}mxs;
+ my $pp = $i . $ap;
+ $p //= '';
+ my ($N, $D);
+ if (my $lp = length $p) {
+ $N = Math::BigInt->new($pp . $p) - Math::BigInt->new($pp);
+ return (0, 1) unless $N;
+ $D = Math::BigInt->new(('9' x length($p)) . ('0' x length($ap)));
+ }
+ else { # non-periodic
+ $N = Math::BigInt->new($pp);
+ $D = Math::BigInt->new('1' . ('0' x length($ap)));
+ }
+ my $g = $N ? gcd($N, $D) : 1;
+ return ($s . ($N / $g), $D / $g);
+}
+
+sub gcd { my ($A, $B) = @_; ($A, $B) = ($B % $A, $A) while $A; return $B }
+
+if (@ARGV == 2) {
+ my ($num, $den) = @ARGV;
+ my $dec = decimal_string($num, $den);
+ say $dec;
+ say {*STDERR} join '/', rational_pair($dec);
+}
+else {
+ require Test::More;
+ Test::More->import;
+ for my $test (
+ [0, 1, '0', 0, 1],
+ [0, -1, '0', 0, 1],
+ [0, 100, '0', 0, 1],
+ [1, 2, '0.5', 1, 2],
+ [3, 6, '0.5', 1, 2],
+ [-1, 2, '-0.5', -1, 2],
+ [1, -2, '-0.5', -1, 2],
+ [11, -22, '-0.5', -1, 2],
+ [14, 7, '2', 2, 1],
+ [14, -7, '-2', -2, 1],
+ [1, 3, '0.(3)', 1, 3],
+ [2, 6, '0.(3)', 1, 3],
+ [1, 7, '0.(142857)', 1, 7],
+ [-3, -21, '0.(142857)', 1, 7],
+ [1, 221, '0.(004524886877828054298642533936651583710407239819)', 1, 221 ],
+ ) {
+ my ($N, $D, $exp_dec, $exp_n, $exp_d) = $test->@*;
+ my $got_dec = decimal_string($N, $D);
+ Test::More::is($got_dec, $exp_dec, "decimal_string($N, $D) is $exp_dec");
+ my ($got_n, $got_d) = rational_pair($exp_dec);
+ Test::More::is($got_n, $exp_n, "numerator for $exp_dec is $exp_n");
+ Test::More::is($got_d, $exp_d, "denominator for $exp_dec is $exp_d");
+ }
+ done_testing();
+}