diff options
| -rwxr-xr-x | challenge-075/e-choroba/perl5/ch-1.pl | 34 | ||||
| -rwxr-xr-x | challenge-075/e-choroba/perl5/ch-2.pl | 90 |
2 files changed, 124 insertions, 0 deletions
diff --git a/challenge-075/e-choroba/perl5/ch-1.pl b/challenge-075/e-choroba/perl5/ch-1.pl new file mode 100755 index 0000000000..9906213aea --- /dev/null +++ b/challenge-075/e-choroba/perl5/ch-1.pl @@ -0,0 +1,34 @@ +#! /usr/bin/perl +use warnings; +use strict; + +# Visible impact for tests #2 and #3. +use Memoize; +memoize('_coins_sum'); + +sub _coins_sum { + my ($sum, @coins) = @_; + my @r; + for my $coin (@coins) { + next if $sum < $coin; + push @r, $sum == $coin + ? [$coin] + : map [ $coin, @$_ ], + grep $_->[0] >= $coin, + do { no warnings 'recursion'; + _coins_sum($sum - $coin, @coins) }; + } + return @r +} + +sub coins_sum { + my ($sum, @coins) = @_; + my @r = _coins_sum($sum, @coins); + return scalar @r +} + +use Test::More tests => 3; + +is coins_sum(6, 1, 2, 4), 6; +is coins_sum(24, 1, 2, 4), 49; +is coins_sum(80, 2, 7), 6; diff --git a/challenge-075/e-choroba/perl5/ch-2.pl b/challenge-075/e-choroba/perl5/ch-2.pl new file mode 100755 index 0000000000..21e90d6385 --- /dev/null +++ b/challenge-075/e-choroba/perl5/ch-2.pl @@ -0,0 +1,90 @@ +#! /usr/bin/perl +use warnings; +use strict; +use feature qw{ say }; +use Syntax::Construct qw{ // }; + +use List::Util qw{ max }; + +sub draw_histogram { + my @columns = @_; + my $max = max(@columns); + my $max_length = length $max; + for my $y (reverse 1 .. $max) { + printf "%${max_length}d ", $y; + say join ' ', map { + sprintf "%${max_length}s", $columns[$_ - 1] >= $y ? '#' : ' ' + } 1 .. @columns; + } + say join ' ', ('_' x $max_length) x (1 + @columns); + printf "%${max_length}s ", ""; + say join ' ', map sprintf("%${max_length}d", $_), @columns; +} + +sub _pop { + my ($max, $smallest, $columns, $column) = @_; + my $s = pop @$smallest; + my $area = $columns->[$s] * ($column - ($smallest->[-1] // -1) - 1); + $$max = $area if $area > $$max; +} + +sub largest_rectangle { + my @columns = @_; + my @smallest; + my $max = 0; + my $column = 0; + while ($column <= $#columns) { + if (! @smallest || $columns[$column] > $columns[ $smallest[-1] ]) { + push @smallest, $column++; + } else { + _pop(\$max, \@smallest, \@columns, $column); + } + } + _pop(\$max, \@smallest, \@columns, $column) while @smallest; + return $max +} + +use Test::More tests => 5; + +{ + open my $stdout, '>', \ my $out; + select $stdout; + draw_histogram(2, 1, 4, 5, 3, 7); + is $out, << '__STDOUT__', 'Print Example 1'; +7 # +6 # +5 # # +4 # # # +3 # # # # +2 # # # # # +1 # # # # # # +_ _ _ _ _ _ _ + 2 1 4 5 3 7 +__STDOUT__ +} + +{ + open my $stdout, '>', \ my $out; + select $stdout; + draw_histogram(2, 10); + is $out, << '__STDOUT__', 'Longer numbers'; +10 # + 9 # + 8 # + 7 # + 6 # + 5 # + 4 # + 3 # + 2 # # + 1 # # +__ __ __ + 2 10 +__STDOUT__ +} + +is largest_rectangle(2, 1, 4, 5, 3, 7), 12, 'Example 1'; +is largest_rectangle(3, 2, 3, 5, 7, 5), 15, 'Example 2'; + +# https://www.geeksforgeeks.org/largest-rectangle-under-histogram/ +is largest_rectangle(6, 2, 5, 4, 5, 1, 6), 12, 'Sumit Ghosh'; |
