diff options
| author | drbaggy <js5@sanger.ac.uk> | 2021-02-17 04:30:45 +0000 |
|---|---|---|
| committer | drbaggy <js5@sanger.ac.uk> | 2021-02-17 04:30:45 +0000 |
| commit | 14b60fde98e0ffe3fa9d415f86c57b011a846374 (patch) | |
| tree | f730c727de6fbf8db25b53da72238959b14cf44e | |
| parent | 21e60474fc0c9a38f930a493a0d9ce0c17fd288f (diff) | |
| download | perlweeklychallenge-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.pl | 55 |
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"; +} |
