diff options
| -rw-r--r-- | challenge-079/daniel-mantovani/blog.txt | 1 | ||||
| -rw-r--r-- | challenge-079/daniel-mantovani/blog1.txt | 1 | ||||
| -rw-r--r-- | challenge-079/daniel-mantovani/perl/ch-1.pl | 39 | ||||
| -rw-r--r-- | challenge-079/daniel-mantovani/perl/ch-2.pl | 78 |
4 files changed, 119 insertions, 0 deletions
diff --git a/challenge-079/daniel-mantovani/blog.txt b/challenge-079/daniel-mantovani/blog.txt new file mode 100644 index 0000000000..85d12babb1 --- /dev/null +++ b/challenge-079/daniel-mantovani/blog.txt @@ -0,0 +1 @@ +https://dev.to/dmanto/perl-weekly-challenge-3269 diff --git a/challenge-079/daniel-mantovani/blog1.txt b/challenge-079/daniel-mantovani/blog1.txt new file mode 100644 index 0000000000..99fdc610c5 --- /dev/null +++ b/challenge-079/daniel-mantovani/blog1.txt @@ -0,0 +1 @@ +https://dev.to/dmanto/perl-weekly-challenge-79-task-2-4n1c diff --git a/challenge-079/daniel-mantovani/perl/ch-1.pl b/challenge-079/daniel-mantovani/perl/ch-1.pl new file mode 100644 index 0000000000..8a4eeb9a1f --- /dev/null +++ b/challenge-079/daniel-mantovani/perl/ch-1.pl @@ -0,0 +1,39 @@ +# TASK #1: Count Set Bits + +# You are given a positive number $N. Write a script +# to count the total numbrer of set bits of the binary +# representations of all numbers from 1 to $N and +# return $total_count_set_bit % 1000000007. + +# Following you will find a "naive" approach to the challenge +# Note that perl already has the capability to get +# a binary expression of an integer, just using +# the sprintf formatter %b, as in +# +# my $binary_string = sprintf("%b", $number); +# +# you can also count how many "1"s you have, +# just use ~= tr/1// as a regex and it will return +# a scalar with the amount of substitutions done +# (i.e, number of 1s in the binary representation) +# +# Also we are supposed to truncate every addition to a modulo 1000000007 +# integer, probably avoiding any overflow on perl arithmetic +# for 32 bit perls (that number is a prime number offen +# used for that purpose) +# +# So our script will just be: + +use strict; +use warnings; +use v5.20; + +my $big_prime = 1_000_000_007; +my $total_count_set_bit = 0; + +for my $n (1 .. shift) { # or $ARGV[0] + $total_count_set_bit += sprintf("%b", $n) =~ tr/1//; + $total_count_set_bit %= $big_prime; +} + +say $total_count_set_bit; diff --git a/challenge-079/daniel-mantovani/perl/ch-2.pl b/challenge-079/daniel-mantovani/perl/ch-2.pl new file mode 100644 index 0000000000..5dd81f4819 --- /dev/null +++ b/challenge-079/daniel-mantovani/perl/ch-2.pl @@ -0,0 +1,78 @@ +use strict; +use warnings; +use v5.20; + +# get input array from command line + +my @N = @ARGV; + +die "usage: perl $0 <space separate numbers (at least 3)>" unless @N > 2; + +# check that all numbers are positive, and find max value + +my $max = -1; +for my $n (@N) { + die "$n is not a proper positive number" unless $n && $n =~ /^\d+$/; + $max = $n if $n > $max; +} + +# we need to take care of the amount of decimal places needed +# form $max, so the histogram can look ok + +my $places = length $max; + +# so the format to print numbers should be: + +my $dfmt = "\%${places}d"; + +my $acc_water = 0; + +for my $r (reverse 1 .. $max) { + + # construct horizontal row, starting from $max + my $line = join('', map { $_ >= $r ? '#' : ' ' } @N); + + # we need to identify in this particular line how many units + # of rain water we can trap. We will replace with a "W" every + # one of those units. + # + # We search for the pattern #< n spaces>#, and as this will + # allow to trap n units, we will replace the spaces with the + # letter "W" + + # Note that after replacing one group, we should start over the + # same line. We cannot continue looking because the last caracter + # matched ('#') may be necesary for the next match. So we cannot + # use a /g to repeat the search, we need to start over the + # matching, but with the spaces changed to "W" so we don't get + # the same match but the following one, if any. + + # For the regex, we use substitution (s///) and we calculate + # the replacement with "W" x length(spaces captured), and leave + # the '#'s in place. /e means we are evaluating the second + # argument, instead of taking it literally + # + while ($line =~ s/#(\s+)#/'#'. 'W' x length($1) . '#'/e) { } + +# units this row can trap is the amount of "W"s we have on it +# feel free to change the tranaliteration operator to tr/W/W/ +# to keep an indication of the allocated water units + $acc_water += $line =~ tr/W/ /; + + # we will add separating spaces between symbols, note we do that after any + # calculation + $line = ' ' . join(' ', split('', $line)); + say sprintf($dfmt, $r) . $line; +} + +# closing line +say " " x ($places - 1) . '_' . ' _' x @N; + +# now print the base rows of the histogram + +for my $i (0 .. $places - 1) { + my $line = join(' ', map { substr(sprintf($dfmt, $_), $i, 1) } @N); + say " " x ($places + 1) . $line; +} + +say "Trapped water: $acc_water"; |
