aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xchallenge-150/jo-37/perl/ch-1.pl85
-rwxr-xr-xchallenge-150/jo-37/perl/ch-2.pl57
2 files changed, 142 insertions, 0 deletions
diff --git a/challenge-150/jo-37/perl/ch-1.pl b/challenge-150/jo-37/perl/ch-1.pl
new file mode 100755
index 0000000000..514b2e4e85
--- /dev/null
+++ b/challenge-150/jo-37/perl/ch-1.pl
@@ -0,0 +1,85 @@
+#!/usr/bin/perl -s
+
+use v5.16;
+use Test2::V0;
+use Coro::Generator;
+use experimental 'signatures';
+
+our ($tests, $examples, $verbose);
+
+run_tests() if $tests || $examples; # does not return
+
+die <<EOS unless @ARGV == 3;
+usage: $0 [-examples] [-tests] [-verbose] [W1 W2 I]
+
+-examples
+ run the examples from the challenge
+
+-tests
+ run some tests
+
+-verbose
+ print intermediate Fibonacci words
+
+W1 W2 I
+ generate Fibonacci words from W1 and W2 until the length I is reached
+ and pick the Ith character
+
+EOS
+
+
+### Input and Output
+
+say pick_from_fib_word(@ARGV);
+
+
+### Implementation
+
+# Generate Fibonacci words from W1 and W2 until the length I is reached
+# and pick the Ith character.
+sub pick_from_fib_word ($w1, $w2, $i) {
+ my $gen = gen_fibonacci_words($w1, $w2);
+ my $f = '';
+ # Generate the needed word and print it in verbose mode.
+ ($f = $gen->(), $verbose) && say $f while $i > length $f;
+
+ substr($f, $i - 1, 1);
+}
+
+# Build a generator for the Fibonacci word sequence starting with W1 and
+# W2.
+sub gen_fibonacci_words ($w1, $w2) {
+ generator {
+ yield $w1;
+ yield $w2;
+ while () {
+ ($w1, $w2) = ($w2, $w1 . $w2);
+ yield $w2;
+ }
+ }
+}
+
+
+### Examples and tests
+
+sub run_tests {
+ SKIP: {
+ skip "examples" unless $examples;
+
+ is pick_from_fib_word(1234, 5678, 51), 7, 'example';
+ }
+
+ SKIP: {
+ skip "tests" unless $tests;
+
+ my $fib_words = gen_fibonacci_words(1234, 5678);
+ is [map $fib_words->(), 1 .. 7],
+ [qw(1234 5678 12345678 567812345678 12345678567812345678
+ 56781234567812345678567812345678
+ 1234567856781234567856781234567812345678567812345678)],
+ 'list of fibonacci words';
+ }
+
+ done_testing;
+ exit;
+}
diff --git a/challenge-150/jo-37/perl/ch-2.pl b/challenge-150/jo-37/perl/ch-2.pl
new file mode 100755
index 0000000000..a1ea3fe1bc
--- /dev/null
+++ b/challenge-150/jo-37/perl/ch-2.pl
@@ -0,0 +1,57 @@
+#!/usr/bin/perl -s
+
+use v5.16;
+use Test2::V0;
+use Math::Prime::Util qw(factor_exp vecmax);
+use Coro::Generator;
+
+our $examples;
+
+run_tests() if $examples; # does not return
+
+die <<EOS unless @ARGV == 1;
+usage: $0 [-examples] [N]
+
+-examples
+ run the examples from the challenge
+
+N
+ Print first N square-free integers.
+
+EOS
+
+
+### Input and Output
+
+main: {
+ my $sq_free = gen_square_free();
+ say $sq_free->() for 1 .. $ARGV[0];
+}
+
+
+### Implementation
+
+# Build a generator for square-free integers.
+sub gen_square_free {
+ generator {
+ # Treat 1 separately as factor(1) returns an empty list.
+ yield 1;
+ for (my $n = 2;; $n++) {
+ # Check if the maximum exponent in N's factorization is one.
+ yield $n if 1 == vecmax map $_->[1], factor_exp $n;
+ }
+ }
+}
+
+
+### Examples and tests
+
+sub run_tests {
+ my $sq_free = gen_square_free();
+ is [map $sq_free->(), 1 .. 19],
+ [1, 2, 3, 5, 6, 7, 10, 11, 13, 14, 15, 17, 19, 21, 22, 23, 26, 29, 30],
+ 'example 1';
+
+ done_testing;
+ exit;
+}