diff options
| author | Jörg Sommrey <28217714+jo-37@users.noreply.github.com> | 2020-11-16 11:54:44 +0100 |
|---|---|---|
| committer | Jörg Sommrey <28217714+jo-37@users.noreply.github.com> | 2020-11-20 18:11:31 +0100 |
| commit | b834dc76110f72a8d5b8908d79e2a64adc52bd1d (patch) | |
| tree | e84a9ecf6fae277361254584321750a7bc6a69c0 | |
| parent | da1ffc2a1a2d010be8ac804e34295c70f7dbd69e (diff) | |
| download | perlweeklychallenge-club-b834dc76110f72a8d5b8908d79e2a64adc52bd1d.tar.gz perlweeklychallenge-club-b834dc76110f72a8d5b8908d79e2a64adc52bd1d.tar.bz2 perlweeklychallenge-club-b834dc76110f72a8d5b8908d79e2a64adc52bd1d.zip | |
Solution to task 1
| -rwxr-xr-x | challenge-087/jo-37/perl/ch-1.pl | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/challenge-087/jo-37/perl/ch-1.pl b/challenge-087/jo-37/perl/ch-1.pl new file mode 100755 index 0000000000..6eaeea9087 --- /dev/null +++ b/challenge-087/jo-37/perl/ch-1.pl @@ -0,0 +1,48 @@ +#!/usr/bin/perl + +use 5.012; +use Test2::V0; +use List::Util qw(reduce uniqnum); +use Data::Dump; + +# Find longest consecutive sequence in a list of integers. An empty +# result in boolean context gives zero as requested. +sub lcs { + # Sort unique values. + my @sorted = uniqnum sort {$a <=> $b} @_; + + # Abusing "reduce" as a sliding window implementation for two + # elements at a time. + # Transform the sorted list into sawtooth shape, where every number + # is shifted to zero if is not the successor of the previous. + my @sawtooth; + my $level; + reduce { + $level = $b if $b != $a + 1; + push @sawtooth, $b - $level; + $b + } '-inf', @sorted; + + # Find the maximum and simultanously its position in the list. + my $maxat = reduce { + $sawtooth[$b] > $a->[0] ? [$sawtooth[$b], $b] : $a + } ['-inf'], 0 .. $#sawtooth; + + # The longest consecutive list ends at the position of the maximum + # and has one more element than the maximum in the sawtooth list. + # Extract this sublist from the ordered list. Empty the result list + # if the maximum is zero, i.e. if the lcs consists of a single + # number. + (@sorted[$maxat->[1] - $maxat->[0] .. $maxat->[1]]) x !!$maxat->[0]; +} + +is [lcs 100, 4, 50, 3, 2], [2, 3, 4], 'Example 1'; +is lcs(20, 30, 10, 40, 50), F(), 'Example 2'; +is [lcs 20, 19, 9, 11, 10], [9, 10, 11], 'Example 3'; + +is [lcs 1, 2, 3, 11, 12, 13, 14, 21, 22], [11, 12, 13, 14], 'max != index'; +is [lcs 12, 3, 1, 14, 5, 2, 11, 3, 4, 13], [1, 2, 3, 4, 5], 'has duplicate'; +is [lcs 1, 2.1, 3.2, 4.3, 5.3, 6.3, 7.2, 8.1, 9], [4.3, 5.3, 6.3], + 'works with broken numbers, too'; + +done_testing; |
