diff options
| -rwxr-xr-x | challenge-173/jo-37/perl/ch-1.pl | 83 | ||||
| -rwxr-xr-x | challenge-173/jo-37/perl/ch-2.pl | 51 |
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; +} |
