diff options
| author | Simon Proctor <simon.proctor@zoopla.co.uk> | 2020-09-21 11:15:23 +0100 |
|---|---|---|
| committer | Simon Proctor <simon.proctor@zoopla.co.uk> | 2020-09-21 11:15:23 +0100 |
| commit | 6c3470c8dab91bd9c3bfdc64c509e701ab798eb1 (patch) | |
| tree | 4e965ee85f54ce1e35a6d52b481f30aa0500e068 | |
| parent | 035364d2ca9ca93bc276349c47fbd1fc4fb1e683 (diff) | |
| download | perlweeklychallenge-club-6c3470c8dab91bd9c3bfdc64c509e701ab798eb1.tar.gz perlweeklychallenge-club-6c3470c8dab91bd9c3bfdc64c509e701ab798eb1.tar.bz2 perlweeklychallenge-club-6c3470c8dab91bd9c3bfdc64c509e701ab798eb1.zip | |
Challenge 2 done
| -rw-r--r-- | challenge-079/simon-proctor/raku/ch-2.raku | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/challenge-079/simon-proctor/raku/ch-2.raku b/challenge-079/simon-proctor/raku/ch-2.raku new file mode 100644 index 0000000000..9824854e3a --- /dev/null +++ b/challenge-079/simon-proctor/raku/ch-2.raku @@ -0,0 +1,63 @@ +#!/usr/bin/env raku + +use v6; + +my %*SUB-MAIN-OPTS = :named-anywhere; + +#| Given a list of height find the area of the largest single rectangle +sub MAIN ( + *@heights where { $_.all ~~ UInt && $_.elems >= 1 } , #= List of height +) { + my @rain-levels = calculate-rain-levels( @heights ); + draw-heights( @heights, @rain-levels ); + say [+] @rain-levels.map(*.area); +} + +class RainArea { + has Range $.range; + has UInt $.height; + has UInt $.area; +} + +sub draw-heights( @heights, @rain ) { + my $max = @heights.max; + my $width = $max.codes; + my $bar = '#' x $width; + my $spc = ' ' x $width; + my $dsh = '-' x $width; + my $wtr = '~' x $width; + my &spr = -> $x { sprintf( "%{$width}d", $x ) } + my &prt = -> $h { + -> $k, $v { + my @found = @rain.grep( -> $r { $k ~~ $r.range } ); + if (@found && $h <= @found[0].height) { + $v >= $h ?? $bar !! $wtr; + } else { + $v >= $h ?? $bar !! $spc; + } + }; + }; + + for $max...1 -> $h { + my &fnc = &prt($h); + ( &spr( $h ), |@heights.kv.map( &fnc ) ).join(" ").say; + } + ( $dsh xx @heights.elems + 1 ).join(" ").say; + ( $spc, |@heights.map( &spr ) ).join(" ").say; +} + +multi sub calculate-rain-levels( @heights where { any(@heights[0^..^*-1]) > any(@heights[0],@heights[*-1]) }, $offset = 0) { + my $max = max(@heights[0^..^*-1]); + my $mid-idx = @heights[0^..^*-1].kv.map( -> $k, $v { $v == $max ?? $k+1 !! Empty } )[0]; + + return ( |calculate-rain-levels( @heights[0..$mid-idx],$offset ), |calculate-rain-levels( @heights[$mid-idx..*],$mid-idx+$offset ) ) +} + +multi sub calculate-rain-levels( @heights where { @heights.elems > 2 }, $offset=0 ) { + my $height = min( @heights[0], @heights[*-1] ); + my $area = $height * ( @heights.elems - 2 ); + $area -= [+] @heights[0^..^*-1]; + return RainArea.new( range => ( $offset..^($offset+@heights.elems) ), :$area, :$height ); +} + +multi sub calculate-rain-levels(@,$) {} |
