aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjuliodcs <julio.dcs@gmail.com>2020-11-21 17:41:24 +0100
committerjuliodcs <julio.dcs@gmail.com>2020-11-21 17:41:24 +0100
commita1fa59df23658bdb0402691bb54d611ede4580a8 (patch)
tree402ef355000d40bcb694736aa7321443c31a1dc0
parentdac3cad558402193f4acc14548c71fdb80a61bc2 (diff)
downloadperlweeklychallenge-club-a1fa59df23658bdb0402691bb54d611ede4580a8.tar.gz
perlweeklychallenge-club-a1fa59df23658bdb0402691bb54d611ede4580a8.tar.bz2
perlweeklychallenge-club-a1fa59df23658bdb0402691bb54d611ede4580a8.zip
juliodcs-week87
-rw-r--r--challenge-087/juliodcs/perl/ch-1.pl48
-rw-r--r--challenge-087/juliodcs/perl/ch-2.pl165
-rw-r--r--challenge-087/juliodcs/raku/ch-1.raku44
-rw-r--r--challenge-087/juliodcs/raku/ch-2.raku188
4 files changed, 445 insertions, 0 deletions
diff --git a/challenge-087/juliodcs/perl/ch-1.pl b/challenge-087/juliodcs/perl/ch-1.pl
new file mode 100644
index 0000000000..7e83004f8c
--- /dev/null
+++ b/challenge-087/juliodcs/perl/ch-1.pl
@@ -0,0 +1,48 @@
+use strict;
+use warnings;
+use experimental 'signatures';
+use feature 'say';
+
+sub _longest($N, $i, $acc, $prev) {
+ if ($i > @{$N} - 1) {
+ my $longest = @{$acc} > @{$prev} ? $acc : $prev;
+ return @{$longest} < 2 ? 0 : $longest;
+ }
+
+ if ($i == 0 || $N->[$i] == $N->[$i - 1] + 1) {
+ push @{$acc}, $N->[$i];
+ }
+ elsif (@{$acc} > @{$prev}) {
+ $prev = $acc;
+ $acc = [];
+ push @{$acc}, $N->[$i];
+ }
+
+ return _longest($N, $i + 1, $acc, $prev)
+}
+
+sub longest_sequence(@N) {
+ my @sorted = sort {$a - $b} @N;
+ return _longest \@sorted, 0, [], [];
+}
+
+if (@ARGV > 0) {
+ use Data::Dumper;
+ say Dumper longest_sequence(@ARGV);
+ exit 0;
+}
+
+use Test::More;
+
+is_deeply longest_sequence(1, 2, 7, 8, 9), [7, 8, 9], 'Tricky test: More elements at the end';
+is_deeply longest_sequence(), 0, 'Empty list has no sequences';
+is_deeply longest_sequence(4), 0, 'One element has no sequence';
+is_deeply longest_sequence(4, 3), [3, 4], 'Two elements';
+is_deeply longest_sequence(4, 3, 2, 1), [1, 2, 3, 4], 'All elements reversed';
+is_deeply longest_sequence(4, 7, 2, 1), [1, 2], 'Two elements out of four';
+is_deeply longest_sequence(4, 7, 2, 1, 5, 99, 6), [4, 5, 6, 7], 'Four elements';
+is_deeply longest_sequence(100, 4, 50, 3, 2), [2, 3, 4], 'Test 1 from PWC';
+is_deeply longest_sequence(20, 30, 10, 40, 50), 0, 'Test 2 from PWC';
+is_deeply longest_sequence(20, 19, 9, 11, 10), [9, 10, 11], 'Test 3 from PWC';
+
+done_testing;
diff --git a/challenge-087/juliodcs/perl/ch-2.pl b/challenge-087/juliodcs/perl/ch-2.pl
new file mode 100644
index 0000000000..53378688b6
--- /dev/null
+++ b/challenge-087/juliodcs/perl/ch-2.pl
@@ -0,0 +1,165 @@
+use strict;
+use warnings;
+use experimental 'signatures';
+use feature 'say';
+
+sub largest_rectangle($matrix) {
+ my $max = q();
+ my $max_offset = length((split(/\R/, $matrix))[0]) - 1;
+ for my $offset (0 .. $max_offset) {
+ while ($matrix =~ m{^.{$offset}(1+).*\R(?=.{$offset}\1)}mg) {
+ $max = $1 if length $max < length $1;
+ }
+ }
+
+ return $max ? ($max . "\n") x 2 : 0;
+}
+
+use Test::More;
+
+is largest_rectangle("1\n1\n"), "1\n1\n", 'Shortest rectangle possible';
+
+is largest_rectangle(<<'EOF'
+111
+011
+EOF
+),
+<<'EOF'
+11
+11
+EOF
+,
+'Small square';
+
+is largest_rectangle(<<'EOF'
+11
+11
+EOF
+),
+"11\n11\n",
+'All ones small';
+
+is largest_rectangle(<<'EOF'
+110
+110
+EOF
+),
+"11\n11\n",
+'Beginning rectangle';
+
+is largest_rectangle(<<'EOF'
+01
+10
+EOF
+),
+0,
+'None found';
+
+is largest_rectangle(<<'EOF'
+00
+11
+00
+EOF
+),
+0,
+'None found again';
+
+is largest_rectangle(<<'EOF'
+1011101
+1111110
+0011111
+1101110
+1111110
+EOF
+),
+<<'EOF'
+1111
+1111
+EOF
+,
+'Big square';
+
+is largest_rectangle(<<'EOF'
+101110
+111100
+001001
+110111
+110111
+EOF
+),
+<<'EOF'
+111
+111
+EOF
+,
+'Several lengths';
+
+is largest_rectangle(<<'EOF'
+000100
+111000
+001001
+111110
+111110
+EOF
+),
+<<'EOF'
+11111
+11111
+EOF
+,
+'Test case 1';
+
+is largest_rectangle(<<'EOF'
+101010
+010101
+101010
+010101
+EOF
+),
+0
+,
+'Test case 2';
+
+is largest_rectangle(<<'EOF'
+000111
+111111
+001001
+001111
+001111
+EOF
+),
+<<'EOF'
+1111
+1111
+EOF
+,
+'Test case 3';
+
+is largest_rectangle(<<'EOF'
+1011101
+1111110
+0011111
+1101110
+1101110
+EOF
+),
+<<'EOF'
+1111
+1111
+EOF
+,
+'Yet another test';
+
+is largest_rectangle(<<'EOF'
+110111
+110111
+EOF
+),
+<<'EOF'
+111
+111
+EOF
+,
+'Biggest rectangle has offset';
+
+done_testing;
diff --git a/challenge-087/juliodcs/raku/ch-1.raku b/challenge-087/juliodcs/raku/ch-1.raku
new file mode 100644
index 0000000000..97124e8f25
--- /dev/null
+++ b/challenge-087/juliodcs/raku/ch-1.raku
@@ -0,0 +1,44 @@
+#! /usr/bin/raku
+
+sub longest-sequence(*@N) {
+ _longest((@N>>.Int).sort, 0, [], [])
+}
+
+sub _longest(@N, $i, @acc, @prev) {
+ if ($i > @N.elems - 1) {
+ my @longest = @acc.elems > @prev.elems ?? @acc !! @prev;
+ return @longest.elems < 2 ?? 0 !! @longest
+ }
+
+ my $add-element := $i == 0 || @N[$i] == @N[$i.pred].succ;
+ my $more-elems := !$add-element && @acc.elems > @prev.elems;
+
+ my @prev-new := $more-elems ?? @acc !! @prev;
+ my @acc-new := $add-element
+ ?? (|@acc, @N[$i])
+ !! $more-elems
+ ?? List.new: @N[$i]
+ !! @acc;
+
+ _longest @N, $i.succ, @acc-new, @prev-new
+}
+
+if @*ARGS.elems > 0 {
+ dd longest-sequence @*ARGS;
+ exit 0
+}
+
+use Test;
+
+is-deeply longest-sequence(1, 2, 7, 8, 9), [7, 8, 9], 'Tricky test: More elements at the end';
+is-deeply longest-sequence(), 0, 'Empty list has no sequences';
+is-deeply longest-sequence(4), 0, 'One element has no sequence';
+is-deeply longest-sequence(4, 3), [3, 4], 'Two elements';
+is-deeply longest-sequence(4, 3, 2, 1), [1, 2, 3, 4], 'All elements reversed';
+is-deeply longest-sequence(4, 7, 2, 1), [1, 2], 'Two elements out of four';
+is-deeply longest-sequence(4, 7, 2, 1, 5, 99, 6), [4, 5, 6, 7], 'Four elements';
+is-deeply longest-sequence(100, 4, 50, 3, 2), [2, 3, 4], 'Test 1 from PWC';
+is-deeply longest-sequence(20, 30, 10, 40, 50), 0, 'Test 2 from PWC';
+is-deeply longest-sequence(20, 19, 9, 11, 10), [9, 10, 11], 'Test 3 from PWC';
+
+done-testing;
diff --git a/challenge-087/juliodcs/raku/ch-2.raku b/challenge-087/juliodcs/raku/ch-2.raku
new file mode 100644
index 0000000000..04e9390855
--- /dev/null
+++ b/challenge-087/juliodcs/raku/ch-2.raku
@@ -0,0 +1,188 @@
+#!/usr/bin/raku
+
+constant ALGORITHM = 1;
+
+say "\n<<Using algorithm {ALGORITHM}>>\n";
+
+sub largest-rectangle($matrix) {
+ my $res = ALGORITHM == 1 ?? largest-rectangle-v1 $matrix !! largest-rectangle-v2 $matrix;
+
+ $res > 0 ?? "{1 x $res}\n" x 2 !! 0
+}
+
+# Solution using regex and loops
+sub largest-rectangle-v1($matrix) {
+ my $max = 0;
+ my $max-offset = $matrix.split(/\s+/).head.chars.pred;
+ for 0 .. $max-offset -> $offset {
+ my $ones = '';
+ for $matrix ~~ m:g/^^ \d**{$offset} (1+) {$ones=$0} (\d*\s+) <?before \d**{$offset} $ones> / {
+ $max = $_[0].chars if $max < $_[0].chars
+ }
+ }
+ $max
+}
+
+# Solution using a single regex a no loops
+sub largest-rectangle-v2($matrix) {
+ my ($pos, $len-pref, $len-ones) = 0, 0, 0;
+ $matrix ~~ m:g{
+ (\d*?) { $len-pref = $0.chars; make 0 } # capture discarded prefix & store its length, initialize result
+ [ \s+ { $pos = 0 } # We reach end of line, reset pos for the next one
+ || (1+) { $len-ones = $1.chars } # capture sequence of ones, store its length
+ <?before # must be followed by:
+ \d* \s+ # rest of line (rest of numbers + new line)
+ \d**{$len-pref + $pos} 1**{$len-ones} # next line: same structure as previous line
+ >
+ { $pos += $len-pref + $len-ones } # update processed position of the current line
+ { make +$len-ones } # prepare result
+ ]
+ } andthen .map(*.made).max # get largest match
+}
+
+use Test;
+
+is largest-rectangle("1\n1\n"), "1\n1\n", 'Shortest rectangle possible';
+
+is largest-rectangle(q:to/END/
+111
+011
+END
+),
+q:to/END/
+11
+11
+END
+,
+'Small square';
+
+is largest-rectangle(q:to/END/
+11
+11
+END
+),
+"11\n11\n",
+'All ones small';
+
+is largest-rectangle(q:to/END/
+110
+110
+END
+),
+"11\n11\n",
+'Beginning rectangle';
+
+is largest-rectangle(q:to/END/
+01
+10
+END
+),
+0,
+'None found';
+
+is largest-rectangle(q:to/END/
+00
+11
+00
+END
+),
+0,
+'None found again';
+
+is largest-rectangle(q:to/END/
+1011101
+1111110
+0011111
+1101110
+1111110
+END
+),
+q:to/END/
+1111
+1111
+END
+,
+'Big square';
+
+is largest-rectangle(q:to/END/
+101110
+111100
+001001
+110111
+110111
+END
+),
+q:to/END/
+111
+111
+END
+,
+'Several lengths';
+
+is largest-rectangle(q:to/END/
+000100
+111000
+001001
+111110
+111110
+END
+),
+q:to/END/
+11111
+11111
+END
+,
+'Test case 1';
+
+is largest-rectangle(q:to/END/
+101010
+010101
+101010
+010101
+END
+),
+0
+,
+'Test case 2';
+
+is largest-rectangle(q:to/END/
+000111
+111111
+001001
+001111
+001111
+END
+),
+q:to/END/
+1111
+1111
+END
+,
+'Test case 3';
+
+is largest-rectangle(q:to/END/
+1011101
+1111110
+0011111
+1101110
+1101110
+END
+),
+q:to/END/
+1111
+1111
+END
+,
+'Yet another test';
+
+is largest-rectangle(q:to/END/
+110111
+110111
+END
+),
+q:to/END/
+111
+111
+END
+,
+'Biggest rectangle has offset';