aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xchallenge-173/jo-37/perl/ch-1.pl83
-rwxr-xr-xchallenge-173/jo-37/perl/ch-2.pl51
2 files changed, 134 insertions, 0 deletions
diff --git a/challenge-173/jo-37/perl/ch-1.pl b/challenge-173/jo-37/perl/ch-1.pl
new file mode 100755
index 0000000000..3857a34d7a
--- /dev/null
+++ b/challenge-173/jo-37/perl/ch-1.pl
@@ -0,0 +1,83 @@
+#!/usr/bin/perl -s
+
+use v5.16;
+use Test2::V0;
+use Math::Prime::Util 'todigits';
+use List::Util 'reduce';
+use experimental 'signatures';
+
+our ($tests, $examples, $base);
+$base ||= 10;
+
+run_tests() if $tests || $examples; # does not return
+
+die <<EOS unless @ARGV;
+usage: $0 [-examples] [-tests] [-base=B] [N]
+
+-examples
+ run the examples from the challenge
+
+-tests
+ run some tests
+
+-base=B
+ Use base B (Default: 10).
+
+N
+ Check if N (decimal) is an "esthetic number" in base B.
+
+EOS
+
+
+### Input and Output
+
+say 0 + !!is_esthetic(shift, $base);
+
+
+### Implementation
+
+# Generalizing the task to arbitrary bases as usual.
+#
+# Taking the liberty of modifying the task slightly. Shouldn't the
+# difference of two digits in a positional representation with base B be
+# taken modulo B? Zero comes after nine in decimal numbers. I'm going
+# to follow this interpretation.
+# A difference D between two digits of one or minus one may be expressed
+# as:
+# (D - 1) * (D + 1) = 0
+# or
+# D ** 2 = 1
+# Taking these equations modulo B, they make "B - 1" and "zero"
+# neighbors.
+
+sub is_esthetic ($n, $base) {
+ # Turn zero to true.
+ defined reduce {
+ # Slide over digit pairs and check their difference.
+ defined $a && ($b - $a)**2 % $base == 1 ? $b : undef
+ } todigits $n, $base;
+}
+
+
+### Examples and tests
+
+sub run_tests {
+ SKIP: {
+ skip "examples" unless $examples;
+
+ ok is_esthetic(5456, 10), 'example 1';
+ ok !is_esthetic(120, 10), 'example 2';
+ }
+
+ SKIP: {
+ skip "tests" unless $tests;
+
+ ok is_esthetic(901, 10), 'nine to zero to one';
+ ok is_esthetic(6969, 4), '1230321(4)';
+ ok is_esthetic(067076, 8), '67076(8)';
+ ok is_esthetic('1234567890987654321012345678909876543210123456789098765432101234567890987654321012345678909876543210123456789098765432101234567890987654321012345678909876543210', 10), 'saw-toothed';
+ }
+
+ done_testing;
+ exit;
+}
diff --git a/challenge-173/jo-37/perl/ch-2.pl b/challenge-173/jo-37/perl/ch-2.pl
new file mode 100755
index 0000000000..d2757717c1
--- /dev/null
+++ b/challenge-173/jo-37/perl/ch-2.pl
@@ -0,0 +1,51 @@
+#!/usr/bin/perl -s
+
+use v5.16;
+use bigint;
+use Test2::V0;
+# Need --force to install, see comment in week 168.
+use List::Gen ':iterate';
+
+our $examples;
+
+run_tests() if $examples; # does not return
+
+die <<EOS unless @ARGV;
+usage: $0 [-examples] [N]
+
+-examples
+ run the examples from the challenge
+
+N
+ Print the first N numbers from Sylvester's sequence.
+
+EOS
+
+
+### Input and Output
+
+gen_sylvester()->say(shift);
+
+
+### Implementation
+
+# Build a generator for Sylvester's sequence using the recurrence
+# relation starting with the value "2".
+sub gen_sylvester {
+ iterate{$_ * ($_ - 1) + 1}->from(2);
+}
+
+
+### Examples and tests
+
+sub run_tests {
+ is gen_sylvester()->take(10),
+ [qw(2 3 7 43 1807 3263443 10650056950807
+ 113423713055421844361000443
+ 12864938683278671740537145998360961546653259485195807
+ 165506647324519964198468195444439180017513152706377497841851388766535868639572406808911988131737645185443)],
+ 'task 2';
+
+ done_testing;
+ exit;
+}