aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrbaggy <js5@sanger.ac.uk>2021-02-17 04:30:45 +0000
committerdrbaggy <js5@sanger.ac.uk>2021-02-17 04:30:45 +0000
commit14b60fde98e0ffe3fa9d415f86c57b011a846374 (patch)
treef730c727de6fbf8db25b53da72238959b14cf44e
parent21e60474fc0c9a38f930a493a0d9ce0c17fd288f (diff)
downloadperlweeklychallenge-club-14b60fde98e0ffe3fa9d415f86c57b011a846374.tar.gz
perlweeklychallenge-club-14b60fde98e0ffe3fa9d415f86c57b011a846374.tar.bz2
perlweeklychallenge-club-14b60fde98e0ffe3fa9d415f86c57b011a846374.zip
add "1-liner" solution & display fn
-rw-r--r--challenge-100/james-smith/perl/ch-2.pl55
1 files changed, 52 insertions, 3 deletions
diff --git a/challenge-100/james-smith/perl/ch-2.pl b/challenge-100/james-smith/perl/ch-2.pl
index 0b00be3ba6..f46b12cf6f 100644
--- a/challenge-100/james-smith/perl/ch-2.pl
+++ b/challenge-100/james-smith/perl/ch-2.pl
@@ -6,11 +6,24 @@ use warnings;
use feature qw(say);
use Test::More;
-is( triangle_sum( [1],[2,4],[6,4,9],[5,1,7,2] ), 8 );
-is( triangle_sum( [3],[3,1],[5,2,3],[4,3,1,3] ), 7 );
+is( triangle_sum( [1],[2,4],[6,4,9],[5,1,7,2] ), 8 );
+is( triangle_sum( [3],[3,1],[5,2,3],[4,3,1,3] ), 7 );
+is( triangle_sum( [2],[3,7],[8,5,6],[6,1,9,3] ), 11 );
+is( triangle_sum( [3],[6,4],[5,2,7],[9,1,8,6] ), 10 );
+
+is( triangle_sum_1point5_liner( [1],[2,4],[6,4,9],[5,1,7,2] ), 8 );
+is( triangle_sum_1point5_liner( [3],[3,1],[5,2,3],[4,3,1,3] ), 7 );
+is( triangle_sum_1point5_liner( [2],[3,7],[8,5,6],[6,1,9,3] ), 11 );
+is( triangle_sum_1point5_liner( [3],[6,4],[5,2,7],[9,1,8,6] ), 10 );
done_testing();
+display_sum( [1],[2,4],[6,4,9],[5,1,7,2] );
+display_sum( [3],[3,1],[5,2,3],[4,3,1,3] );
+display_sum( [2],[3,7],[8,5,6],[6,1,9,3] );
+display_sum( [3],[6,4],[5,2,7],[9,1,8,6] );
+
+
## 72 chars ############################################################
## There are two directions you can go with this problem (up or down)
@@ -26,8 +39,44 @@ sub triangle_sum {
## Strip off base of triangle...
my $b = pop @tri;
## Update new last line by adding smallest of it's "children"
- $tri[-1][$_] += $b->[$b->[$_]<$b->[$_+1]?$_:$_+1] for 0..@tri-1;
+ $tri[-1][$_] += $b->[
+ $b->[$_] < $b->[$_+1] ? $_ : $_+1
+ ] for 0..@tri-1;
}
return $tri[0][0];
}
+## We can convert the inner for loop into a map... and pop the value
+## of $b in the while clause so we can simplify this down to a single
+## one line statement, with the return just returning the last
+## element of $b - here we are using the implicit my $b & return
+##
+## so not quite a 1 liner - but close enough!!
+
+sub triangle_sum_1point5_liner {
+ @{$_[-1]} = map {
+ $_[-1][$_] + $b->[ $b->[$_] < $b->[$_+1] ? $_ : $_+1 ]
+ } 0..@_-1 while @{$b=pop @_}>1;
+ $b->[0];
+}
+
+sub display_sum {
+ my @tri = @_;
+ my @route;
+ while(@{$b = pop @tri}>1) {
+ ($tri[-1][$_],$route[$_]) = $b->[$_]<$b->[$_+1]
+ ? ( $tri[-1][$_] + $b->[$_], [$_, @{$route[$_ ]||[]}] )
+ : ( $tri[-1][$_] + $b->[$_+1], [$_+1,@{$route[$_+1]||[]}] ) foreach 0..@tri-1;
+ }
+ @route = (0,@{$route[0]});
+ print
+ '',
+ ( map {
+ ' ' x (@_-($a=$_)),
+ ( map {
+ sprintf $route[$a]==$_ ? '[%d] ': ' %d ' , $_[$a][$_]
+ } 0..$a ),
+ "\n"
+ } 0..@_-1 ),
+ "\n";
+}