aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2019-08-04 00:09:02 +0100
committerGitHub <noreply@github.com>2019-08-04 00:09:02 +0100
commit745e1e0e4bf2f124c5b8c1e3220b725e47ef6654 (patch)
tree841854137c7cc4405ff3394614849bb329a9c166
parentb0ab041a642a1f42c48059c593048d06eb4baa89 (diff)
parentdb1256b5b77752b1c79464cfa065a31b3eb381dd (diff)
downloadperlweeklychallenge-club-745e1e0e4bf2f124c5b8c1e3220b725e47ef6654.tar.gz
perlweeklychallenge-club-745e1e0e4bf2f124c5b8c1e3220b725e47ef6654.tar.bz2
perlweeklychallenge-club-745e1e0e4bf2f124c5b8c1e3220b725e47ef6654.zip
Merge pull request #462 from dmanto/branch-for-challenge-019
my proposed solutions for challenge-019, p5 1 & 2
-rw-r--r--challenge-019/daniel-mantovani/perl5/ch-1.pl97
-rw-r--r--challenge-019/daniel-mantovani/perl5/ch-2.pl61
2 files changed, 158 insertions, 0 deletions
diff --git a/challenge-019/daniel-mantovani/perl5/ch-1.pl b/challenge-019/daniel-mantovani/perl5/ch-1.pl
new file mode 100644
index 0000000000..a4b05ef62c
--- /dev/null
+++ b/challenge-019/daniel-mantovani/perl5/ch-1.pl
@@ -0,0 +1,97 @@
+# Write a script to display months from the year 1900 to 2019 where
+# you find 5 weekends i.e. 5 Friday, 5 Saturday and 5 Sunday.
+
+use strict;
+use warnings;
+
+# We start by noting that in order to have 3 weekday with 5
+# ocurrences, the month should have 31 days.
+# This is because, as a minimum, you will need:
+#
+# 3 weekdays * 5 repetitions = 15 days
+# 4 weekdays * 4 repetitions = 16 days
+# -------
+# Total days 31 days
+#
+# and as there are no month longer than that, our
+# month will have to be exactly 31 days long
+#
+# But not every 31 day month will have 3 weekends. Let's see
+# for example:
+#
+# Aug 2019
+#
+# S M T W T F S
+# 1 2 3
+# 4 5 6 7 8 9 10
+# 11 12 13 14 15 16 17
+# 18 19 20 21 22 23 24
+# 25 26 27 28 29 30 31
+#
+# ^ ^ ^ ^
+# | | | |____ 5 Saturdays ☑️
+# | | |_______ 5 Fridays ☑️
+# | |__________ 5 Thursdays 🤷🏻‍♂️
+# |______________________ but only 4 Sundays 😖
+#
+# Looking at this example, it should be clear that
+# the 2nd requisite to have 5 weekends is that 1st
+# of month be a Friday
+#
+# Of course we could use an advanced module to ease
+# day / month calculations, like DateTime (which by the
+# way is the Kensho-recommended one), but it will probably
+# not be that challenging to do so.
+#
+# Instead we are going to reuse many concepts from challenge-013-1,
+# and just use the core Time::Local module to calculate first day
+# epoch value.
+# We will always use GMT/UTC variant for epoch calculations, just
+# to be consistent.
+#
+
+use Time::Local;
+
+my $epoch = timegm( 0, 0, 12, 1, 0, 1900 ); # January 1st 1900, 12 noon epoch
+my $oneday = 24 * 3600; # one day in seconds
+
+#
+# Now we start calculating month by month, checking if it
+# is a 31 day month, and also if 1st day of the month
+# is a Friday
+#
+
+while ( ( gmtime($epoch) )[5] <= 119 ) {
+
+ # note that gmtime's [5] response position is year minus 1900,
+ # so we are just asking if $epoch correspond to a year less or
+ # equal to 2019 to stay in the while loop
+ #
+ # first we calculate the 1st day of next month.
+ # to do that, note that $epoch + 40 * $oneday will fall into next
+ # month for sure. Then substracting the amount of new day of the
+ # month and adding one we are for sure on the 1st day of the next
+ # month
+
+ my $next_month_epoch = $epoch + 40 * $oneday;
+ $next_month_epoch -= ( ( gmtime($next_month_epoch) )[3] - 1 ) * $oneday;
+
+ # so if for example $next_month_epoch corresponds to day 7, it will substract
+ # 6 whole days, so $next_month_epoch will be corrected to represent
+ # day 1 of next month
+
+ # now we check if $epoch is a Friday, and if last day of current
+ # month is 31
+
+ if ( ( gmtime($epoch) )[6] == 5
+ && ( gmtime( $next_month_epoch - $oneday ) )[3] == 31 )
+ {
+ # found a match. Just adjust gmtime's result to properly
+ # show month and year, and then print the result
+ my ( $month, $year ) = ( gmtime($epoch) )[ 4, 5 ];
+ printf "Found 5 weekend month: %u/%u\n", $month + 1, $year + 1900;
+ }
+
+ # now we just repeat the loop with next month epoch
+ $epoch = $next_month_epoch;
+}
diff --git a/challenge-019/daniel-mantovani/perl5/ch-2.pl b/challenge-019/daniel-mantovani/perl5/ch-2.pl
new file mode 100644
index 0000000000..7ccebf65f2
--- /dev/null
+++ b/challenge-019/daniel-mantovani/perl5/ch-2.pl
@@ -0,0 +1,61 @@
+# Write a script that can wrap the given paragraph
+# at a specified column using the greedy algorithm.
+
+use strict;
+use warnings;
+use v5.10;
+use utf8;
+use open qw(:std :utf8);
+
+# greedy algorithm basically means put as many words
+# on a line as possible
+#
+# let's start by defining a "fmt" function, that
+# you will call with the text and the desired line width
+
+sub fmt {
+ my ( $text, $line_width ) = @_;
+ my $out = ''; # final formatted text will be here
+ my $current_line = ''; # we will be adding words (while they fit) here
+ for my $w ( split /\s+/, $text ) {
+
+ # this split will return an array of "non-space" words. Note that
+ # the amount of consecutive space characters doesn't matter, as
+ # long there is at least one
+ if ( length("$current_line $w") > $line_width ) {
+
+ # a space plus $w does not fit in current line
+ # close current line and start a new one with
+ # just $w
+ $out .= "$current_line\n";
+ $current_line = $w;
+ }
+ else {
+ # here we just append a space and $w to current line
+ # actually the space is appended only when $current_line
+ # is not empty, (i.e. is not the first word of the text)
+ $current_line .= ' ' if length $current_line;
+ $current_line .= $w;
+ }
+ }
+
+ # we still need to add our current line at the end
+ $out .= "$current_line" if length $current_line;
+ return $out;
+}
+
+#
+# an example:
+#
+
+my $example_text = '
+Lorem ipsum dolor sit amet, consectetur adipiscing elit,
+sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+Ut enim ad minim veniam, quis nostrud exercitation ullamco
+laboris nisi ut aliquip ex ea commodo consequat.
+Duis aute irure dolor in reprehenderit in voluptate velit
+esse cillum dolore eu fugiat nulla pariatur.
+Excepteur sint occaecat cupidatat non proident,
+sunt in culpa qui officia deserunt mollit anim id est laborum.
+';
+say fmt( $example_text, 60 );