From 45bfa9e1ca29c855329c43f51220c2ad991dbd24 Mon Sep 17 00:00:00 2001 From: Jörg Sommrey <28217714+jo-37@users.noreply.github.com> Date: Wed, 18 Jan 2023 17:35:35 +0100 Subject: Add solution to James Smith's benchmarks for challenge 199/2 --- challenge-199/jo-37/perl/ch-2.pl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/challenge-199/jo-37/perl/ch-2.pl b/challenge-199/jo-37/perl/ch-2.pl index 292be9b25e..ef5a11b322 100755 --- a/challenge-199/jo-37/perl/ch-2.pl +++ b/challenge-199/jo-37/perl/ch-2.pl @@ -83,3 +83,19 @@ sub run_tests { done_testing; exit; } + +__DATA__ + +Out of curiosity, rerun James Smith's benchmarks with this +implementation added. See +https://github.com/manwar/perlweeklychallenge-club/blob/master/challenge-199/james-smith/perl/ch-2.pl + + Rate naive opt range_1 copy_1 copy_2 range_2 fastest pdl +naive 21.5/s -- -49% -52% -53% -56% -64% -84% -90% +opt 41.9/s 95% -- -7% -8% -13% -29% -70% -81% +range_1 45.1/s 110% 8% -- -1% -7% -24% -67% -79% +copy_1 45.8/s 113% 9% 1% -- -5% -22% -67% -79% +copy_2 48.4/s 125% 15% 7% 6% -- -18% -65% -78% +range_2 59.0/s 174% 41% 31% 29% 22% -- -57% -73% +fastest 138/s 543% 230% 207% 202% 186% 134% -- -36% +pdl 218/s 912% 419% 382% 375% 350% 269% 57% -- -- cgit From a175236c84a2b91dca97627a0e3b4d777cbe40f7 Mon Sep 17 00:00:00 2001 From: Jörg Sommrey <28217714+jo-37@users.noreply.github.com> Date: Mon, 16 Jan 2023 18:47:14 +0100 Subject: Solution to task 1 --- challenge-200/jo-37/perl/ch-1.pl | 124 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100755 challenge-200/jo-37/perl/ch-1.pl diff --git a/challenge-200/jo-37/perl/ch-1.pl b/challenge-200/jo-37/perl/ch-1.pl new file mode 100755 index 0000000000..422065663b --- /dev/null +++ b/challenge-200/jo-37/perl/ch-1.pl @@ -0,0 +1,124 @@ +#!/usr/bin/perl -s + +use v5.16; +use Test2::V0 '!float'; +use PDL; +use PDL::NiceSlice; +use experimental 'postderef'; + +our ($tests, $examples); + +run_tests() if $tests || $examples; # does not return + +die < ((a + b + c) - (c + b + a), (a + b + c) - (c + b), + # (a + b + c) - c) = (0, a, a + b) + # The total sum over the run length equals the length of the list of + # differences which is one less than the original list's length. + my $idx = $l->dim(0) - 1 - $rl(-1:0)->cumusumover->(-1:0); + + # The differences' run lengths are one below the subarray lengths, + # adjust them. + $rl += 1; + + # Select subarrays having a minimum length of three, given by their + # starting index and their length. + my @res; + for my $il (cat(where $idx, $rl, $rl > 2)->xchg(0, 1)->dog) { + # Pick a maximal arithmetic array slice given by index and + # lenght. + my $maas = $l->range($il->list); + + # Split each maximal arithmetic array slice into all requested + # array slices and collect these. + push @res, map $maas->lags(0, 1, $_) + ->xchg(0, 1)->(-1:0)->unpdl->@*, 3 .. $maas->dim(0); + } + + @res; +} + +### Examples and tests + +sub run_tests { + SKIP: { + skip "examples" unless $examples; + + is [arith_slices(1, 2, 3, 4)], + [[1, 2, 3], [2, 3, 4], [1, 2, 3, 4]], 'example 1'; + + is [arith_slices(2)], [], 'example 2'; + + } + + SKIP: { + skip "tests" unless $tests; + + is [arith_slices(1, 2, 3, 4, 3, 5, 7)], + [[1, 2, 3], [2, 3, 4], [1, 2, 3, 4], [3, 5, 7]], + 'different step sizes'; + + is [arith_slices(-2, 0, 2)], [[-2, 0, 2]], 'negative value'; + + is [arith_slices(1, 2, 3, 5, 7)], [[1, 2, 3], [3, 5, 7]], + 'adjacent slices'; + + is [arith_slices(0, 0, 0, 0)], [[0, 0, 0], [0, 0, 0], [0, 0, 0, 0]], + 'slices having equal values'; + } + + done_testing; + exit; +} -- cgit From d5f8cdf7d6266cf0ab3a99b3c7545417d4b19e41 Mon Sep 17 00:00:00 2001 From: Jörg Sommrey <28217714+jo-37@users.noreply.github.com> Date: Mon, 16 Jan 2023 18:47:24 +0100 Subject: Solution to task 2 --- challenge-200/jo-37/perl/ch-2.pl | 159 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100755 challenge-200/jo-37/perl/ch-2.pl diff --git a/challenge-200/jo-37/perl/ch-2.pl b/challenge-200/jo-37/perl/ch-2.pl new file mode 100755 index 0000000000..85df4078e0 --- /dev/null +++ b/challenge-200/jo-37/perl/ch-2.pl @@ -0,0 +1,159 @@ +#!/usr/bin/perl -s + +use v5.16; +use Test2::V0 '!float'; +use PDL; +use PDL::NiceSlice; +use experimental qw(signatures postderef); + +our ($tests, $examples, $p, $q); +$p //= 7; +$q //= 5; +die "p too small" if $p < 5; +die "q too small" if $q < 5; + + +run_tests() if $tests || $examples; # does not return + +die <range([[0, 0], [0, $l]], [$p, $l], 't'); + # Draw a segment. + $ul($_->@[1..3]) .= ord $_->[0]; + $s; + } @segments + )->reorder(2, 0, 1); + } +} + +# Convert the truth table to an array of index piddles representing +# the corresponding segments. +sub decto7 { + map indx(map ord, split //) - ord('a'), + qw; +} + +sub say_seven_segments ($p, $q, $n) { + my $segments = segments($p, $q); + my @decto7 = decto7; + + # Create a (P*L)xQ piddle holding the pixels of the given number + # (with L as the length of N) by concatenating the individual + # digits' pixels line-wise. + my $out = byte cat( + # Select the segments as given by the truth table for every + # single digit and combine them. + map $segments($decto7[$_])->sumover, split //, $n + )->clump(0, 2); + + # Print the pixels line-wise, mapping zero to blank and non-zero + # to the corresponding character. + say map $_ ? chr : ' ', $_->list for $out->dog; +} + + +### Examples and tests + +sub run_tests { + use autodie; + + SKIP: { + skip "examples" unless $examples; + + say_seven_segments(9, 7, 200); # Sized like the example + } + + SKIP: { + skip "tests" unless $tests; + + open my $save, '>&', \*STDOUT; + close STDOUT; + open STDOUT, '>', \my $capture; + + say_seven_segments(7, 5, 8); + + close STDOUT; + open STDOUT, '>&', $save; + + is $capture, <