From 1b7b64b0c0918f2a21d58981b435faceb95610c7 Mon Sep 17 00:00:00 2001 From: Simon Proctor Date: Tue, 25 Aug 2020 13:56:37 +0100 Subject: Largest rectangle. With graphs --- challenge-075/simon-proctor/raku/ch-2.raku | 43 ++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 challenge-075/simon-proctor/raku/ch-2.raku diff --git a/challenge-075/simon-proctor/raku/ch-2.raku b/challenge-075/simon-proctor/raku/ch-2.raku new file mode 100644 index 0000000000..4497f86c7a --- /dev/null +++ b/challenge-075/simon-proctor/raku/ch-2.raku @@ -0,0 +1,43 @@ +#!/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 ( + Bool :g(:$graph-heights) = False, #=Draw the height histogram first + *@heights where { $_.all ~~ UInt && $_.elems >= 1 } , #= List of height +) { + draw-heights( @heights ) if $graph-heights; + say calculate-max-rect( @heights ); +} + +sub draw-heights( @heights ) { + my $max = @heights.max; + my $width = $max.codes; + my $bar = '#' x $width; + my $spc = ' ' x $width; + my $dsh = '-' x $width; + my &spr = -> $x { sprintf( "%{$width}d", $x ) } + + for $max...1 -> $h { + ( &spr( $h ), |@heights.map( { $_ >= $h ?? $bar !! $spc } ) ).join(" ").say; + } + ( $dsh xx @heights.elems + 1 ).join(" ").say; + ( $spc, |@heights.map( &spr ) ).join(" ").say; +} + +sub calculate-max-rect( @heights ) { + my $length = @heights.elems - 1; + + my @ranges = ( (0..$length) X (0..$length) ).grep( { $_[0] <= $_[1] } ); + my $max = 0; + + for @ranges -> ($s,$e) { + my $height = @heights[$s..$e].min; + my $area = $height * ($e - $s + 1); + $max = $area if $max < $area; + } + return $max; +} -- cgit