diff options
| author | Jörg Sommrey <28217714+jo-37@users.noreply.github.com> | 2023-03-31 14:41:29 +0200 |
|---|---|---|
| committer | Jörg Sommrey <28217714+jo-37@users.noreply.github.com> | 2023-03-31 14:41:29 +0200 |
| commit | b1dbb201a295d2cc047a10e8c2f07fba8ff57b98 (patch) | |
| tree | bfb8661acd93c5b07a377ce8cf972c0a09894197 | |
| parent | 8915a66de2cb2a724aee5e55ddfc15580cfdf1d5 (diff) | |
| parent | 02acd68ba59a08522e2ab6549cc5ca635079666a (diff) | |
| download | perlweeklychallenge-club-b1dbb201a295d2cc047a10e8c2f07fba8ff57b98.tar.gz perlweeklychallenge-club-b1dbb201a295d2cc047a10e8c2f07fba8ff57b98.tar.bz2 perlweeklychallenge-club-b1dbb201a295d2cc047a10e8c2f07fba8ff57b98.zip | |
Solutions to challenge 210
| -rwxr-xr-x | challenge-210/jo-37/perl/ch-1.pl | 64 | ||||
| -rwxr-xr-x | challenge-210/jo-37/perl/ch-2.pl | 100 |
2 files changed, 164 insertions, 0 deletions
diff --git a/challenge-210/jo-37/perl/ch-1.pl b/challenge-210/jo-37/perl/ch-1.pl new file mode 100755 index 0000000000..8a8aef7f2e --- /dev/null +++ b/challenge-210/jo-37/perl/ch-1.pl @@ -0,0 +1,64 @@ +#!/usr/bin/perl -s + +use v5.16; +use Test2::V0; +use List::Util qw(sum max); +use List::UtilsBy qw(count_by); + +our ($tests, $examples); + +run_tests() if $tests || $examples; # does not return + +die <<EOS unless @ARGV; +usage: $0 [-examples] [-tests] [--] [N...] + +-examples + run the examples from the challenge + +-tests + run some tests + +N... + list of numbers + +EOS + + +### Input and Output + +say kill_and_win(@ARGV); + + +### Implementation + +# Brute force implementation. + +sub kill_and_win { + # Create a map from values to their frequencies. + my %freq = count_by {$_} @_; + # Find the maximum over three consectutive values. + max map { + sum map {$_ * ($freq{$_} // 0)} $_ - 1, $_, $_ + 1 + } keys %freq; +} + + +### Examples and tests + +sub run_tests { + SKIP: { + skip "examples" unless $examples; + + is kill_and_win(2, 3, 1), 6, 'example 1'; + is kill_and_win(1, 1, 2, 2, 2, 3), 11, 'example 2'; + } + + SKIP: { + skip "tests" unless $tests; + + is kill_and_win(1, 1, 2, 2, 3, 3, 13), 13, 'single large value'; + } + + done_testing; + exit; +} diff --git a/challenge-210/jo-37/perl/ch-2.pl b/challenge-210/jo-37/perl/ch-2.pl new file mode 100755 index 0000000000..8354c1fbd7 --- /dev/null +++ b/challenge-210/jo-37/perl/ch-2.pl @@ -0,0 +1,100 @@ +#!/usr/bin/perl -s + +use v5.22; +use Test2::V0; +use List::MoreUtils 'zip6'; +use experimental 'refaliasing'; + +our ($tests, $examples); + +run_tests() if $tests || $examples; # does not return + +die <<EOS unless @ARGV; +usage: $0 [-examples] [-tests] [--] [NUM...] + +-examples + run the examples from the challenge + +-tests + run some tests + +NUM... + list of numbers + +EOS + + +### Input and Output + +say "(@{number_collision(@ARGV)})"; + + +### Implementation + +# Maybe there is a way to solve this puzzle just by looking at the +# numbers. I don't see one. So we're going play the game to find the +# result. + +sub number_collision { + # Distribute the numbers onto two arrays depending on the sign, + # which defines the moving direction. Inserting 'undef' to keep + # every number's position. + my (@right, @left); + for (@_) { + push @left, $_ < 0 ? $_ : undef; + push @right, $_ < 0 ? undef : $_; + } + # Our 'frame of reference' is given by the numbers moving left, i.e. + # negative values never change their position, whereas positive + # number are shifted to the right. + # Initialise two index positions of + # - the leftmost positive number + # - the rightmost negative number + my ($r, $l) = (0, 'inf'); + # As long as the first index is smaller than the second, there are + # collisions ahead. + while ($r < $l) { + ($r, $l) = ('inf', 0); + # Move right. + unshift @right, undef; + # Process all number pairs. + for my $i (0 .. $#right) { + # Get a shorthand for the pair. + \my ($ri, $li) = \($right[$i], $left[$i]); + # Get the pair's values with default. + my ($ri_d, $li_d) = ($ri // -1, $li // 1); + # Find the result of a collision. + ($ri, $li) = ( $ri_d <= -$li_d ? undef : $ri, + -$li_d <= $ri_d ? undef : $li); + # Adjust indices. + $r = $i if defined $ri && $i < $r; + $l = $i if defined $li; + } + } + [map $_->[0] // $_->[1] // (), zip6 @right, @left]; + +} + + +### Examples and tests + +sub run_tests { + SKIP: { + skip "examples" unless $examples; + + is number_collision(2, 3, -1), [2, 3], 'example 1'; + is number_collision(2, 3, -4), [-4], 'example 2'; + is number_collision(1, -1), [], 'example 3'; + } + + SKIP: { + skip "tests" unless $tests; + + is number_collision(0), [0], 'surviving zero'; + is number_collision(1, -2, 3, 1, -3, 4, 2, -4, 5, 3, 1, -6), + [-2, -6], 'the big pwc number massacre'; + } + + done_testing; + exit; +} |
