aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xchallenge-075/e-choroba/perl5/ch-1.pl34
-rwxr-xr-xchallenge-075/e-choroba/perl5/ch-2.pl90
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';