From 656b809b747b8b8081b4f5a9a8d93d3c6703a6d0 Mon Sep 17 00:00:00 2001 From: Niels van Dijke Date: Tue, 22 Sep 2020 17:41:47 +0000 Subject: Task 1 & 2 --- challenge-079/perlboy1967/perl/ch-1.pl | 39 +++++++++++ challenge-079/perlboy1967/perl/ch-2.pl | 117 +++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100755 challenge-079/perlboy1967/perl/ch-1.pl create mode 100755 challenge-079/perlboy1967/perl/ch-2.pl diff --git a/challenge-079/perlboy1967/perl/ch-1.pl b/challenge-079/perlboy1967/perl/ch-1.pl new file mode 100755 index 0000000000..911cda875d --- /dev/null +++ b/challenge-079/perlboy1967/perl/ch-1.pl @@ -0,0 +1,39 @@ +#!/usr/bin/perl + +# Perl Weekly Challenge - 079 +# - https://perlweeklychallenge.org/blog/perl-weekly-challenge-079/ +# +# Task 1 - Count Set Bits +# +# Author: Niels 'PerlBoy' van Dijke + +use strict; +use warnings; + +use constant SOME_VALUE => 1000000007; + +my ($N) = @ARGV; + +die "N must be positive integer value" + unless (defined $N and $N =~ m#^[1-9][0-9]*$#); + +my $bits = countBits($N); + +printf "Input: %d\n", $N; +printf "Output: %d %% %d = %d\n", + $bits, + SOME_VALUE(), + $bits % SOME_VALUE(); + +sub countBits { + my ($n) = @_; + + my $b = 0; + + map { + # Some 'unpack/pack' black magic + $b += unpack('%32b*', pack('I', $_)); + } (1 .. $n); + + return $b; +} diff --git a/challenge-079/perlboy1967/perl/ch-2.pl b/challenge-079/perlboy1967/perl/ch-2.pl new file mode 100755 index 0000000000..04f6c69762 --- /dev/null +++ b/challenge-079/perlboy1967/perl/ch-2.pl @@ -0,0 +1,117 @@ +#!/usr/bin/perl + +# Perl Weekly Challenge - 079 +# - https://perlweeklychallenge.org/blog/perl-weekly-challenge-079/ +# +# Task 2 - Trapped Rain Water +# +# Author: Niels 'PerlBoy' van Dijke + +use strict; +use warnings; + +use List::Util qw(min max); +use List::MoreUtils qw(uniq indexes); + + +my (@N) = @ARGV; +@N = (1, 2, 1, 1, 10, 3, 4, 1, 2, 7, 2, 2, 4, 1, 2, 1, 3, 2) + unless scalar @N; + +die "N must be a list of at least 3 positive integer values" + unless (scalar @N >= 3 and !scalar(grep { !/^[1-9][0-9]*$/ } @N)); + + +my $grid = createHistGrid(\@N); +printHistogram('Input:', $grid, \@N); +my $trappedWater = findAndFillGaps(\@N, $grid); +printHistogram('Output:', $grid, \@N, $trappedWater); + + +sub createHistGrid { + my ($arList) = @_; + + my $grid = []; + + my $max = max(@$arList); + + foreach my $y (0 .. $max - 1) { + foreach my $x (0 .. scalar @$arList - 1) { + $grid->[$x][$y] = ($arList->[$x] > $y ? '#' : ' '); + } + } + + return $grid; +} + + +sub findAndFillGaps { + my ($arL, $grid) = @_; + + my $dropsAdded = 0; + + my @list = @$arL; + + my @levels = sort {$b <=> $a } uniq(@list); + + foreach my $level (@levels) { + my @i = indexes { $_ >= $level } @list; + next unless (scalar(@i) > 1); + + do { + my $i = shift(@i); + last if (!defined $i[0]); + + if ($i[0] - $i > 1) { + my $fillLevel = min($list[$i], $list[$i[0]]); + + for my $j ($i + 1 .. $i[0] - 1) { + for my $k ($list[$j] + 1 .. $fillLevel) { + $grid->[$j][$k - 1] = '.'; + } + $dropsAdded += ($fillLevel - $list[$j]); + $list[$j] = $fillLevel; + } + } + } while (scalar @i > 1); + } + + return $dropsAdded; +} + + +sub printHistogram { + my ($caption, $arGrid, $arList, $trappedWater) = @_; + + my $max = max(@$arList); + my $yLw = length($max); + + print "$caption\n"; + + # Print histogram rows + for (my $row = $max; $row > 0; $row--) { + my @row = (sprintf("%${yLw}s", $row), '|'); + for my $col (0 .. scalar(@$arList) - 1) { + push(@row, $grid->[$col][$row - 1]); + } + print join(" ", @row)."\n"; + } + + # Print X-axis + print sprintf("%${yLw}s +%s\n", + '', + join('-', map { '-' } @$arList, '')); + + # Print X labels + for my $l (0 .. $yLw - 1) { + print sprintf("%${yLw}s %s\n", + '', + join(' ', map { substr($_.' ' x $yLw, $l, 1) } @$arList)); + } + + if (defined $trappedWater) { + printf "\nAmount of trapped waterdrops: %d (marked with '.' in histogram).\n", $trappedWater; + } + + print "\n"; +} -- cgit