aboutsummaryrefslogtreecommitdiff
path: root/challenge-019
diff options
context:
space:
mode:
authorDaniel Mantovani <daniel@gmail.com>2019-08-03 16:37:56 -0300
committerDaniel Mantovani <daniel@gmail.com>2019-08-03 16:37:56 -0300
commit981c3ecf47372c2d236ceba62e4f2da0b95094fc (patch)
treeba86ebc0a8071d5cb51b5cd48c6d82e29560ade8 /challenge-019
parent4c2c55fef51a2ddfed57a9b41fe9d94ef0f78c97 (diff)
downloadperlweeklychallenge-club-981c3ecf47372c2d236ceba62e4f2da0b95094fc.tar.gz
perlweeklychallenge-club-981c3ecf47372c2d236ceba62e4f2da0b95094fc.tar.bz2
perlweeklychallenge-club-981c3ecf47372c2d236ceba62e4f2da0b95094fc.zip
my proposed solutions for challenge-019, p5 1 & 2
Diffstat (limited to 'challenge-019')
-rw-r--r--challenge-019/daniel-mantovani/perl5/ch-1.pl97
-rw-r--r--challenge-019/daniel-mantovani/perl5/ch-2.pl61
-rw-r--r--challenge-019/daniel-mantovani/perl5/perltidy.LOG40
3 files changed, 198 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 );
diff --git a/challenge-019/daniel-mantovani/perl5/perltidy.LOG b/challenge-019/daniel-mantovani/perl5/perltidy.LOG
new file mode 100644
index 0000000000..b5172e3a4d
--- /dev/null
+++ b/challenge-019/daniel-mantovani/perl5/perltidy.LOG
@@ -0,0 +1,40 @@
+perltidy version 20180220 log file on a darwin system, OLD_PERL_VERSION=5.028000
+Configuration and command line parameters for this run:
+-st -profile=.../.perltidyrc
+To find error messages search for 'WARNING' with your editor
+Indentation will be with 4 spaces
+Line 4 implies starting-indentation-level = 0
+
+######################## WARNING #########################
+82: my ( $month, $year ) = @( gtime($epoch)[ 4, 5 ] );
+ -- ^
+found bareword where operator expected (previous token underlined)
+############################################################
+
+######################## WARNING #########################
+There is no previous '(' to match a ')' on line 82
+82: my ( $month, $year ) = @( gtime($epoch)[ 4, 5 ] );
+ ^
+############################################################
+The nesting depths in the table below are at the start of the lines.
+The indicated output line numbers are not always exact.
+ci = levels of continuation indentation; bk = 1 if in BLOCK, 0 if not.
+
+in:out indent c b nesting code + messages; (messages begin with >>>)
+lines levels i k (code begins with one '.' per indent level)
+------ ----- - - -------- -------------------------------------------
+L50:50 i0:0 0 1 my $epoch = timegm( 0, 0, 12, 1, 0, ....
+L86:86 i0:0 0 1 {{)} >>>WARNING: Program bug in scan_list: hit nesting error which should have been caught
+No indentation disagreement seen
+
+No lines exceeded 80 characters
+ Maximum output line length was 80 at line 50
+WARNING: To save a full .LOG file rerun with -g
+WARNING:
+Oops, you seem to have encountered a bug in perltidy. Please check the
+BUGS file at http://perltidy.sourceforge.net. If the problem is not
+listed there, please report it so that it can be corrected. Include the
+smallest possible script which produces this message, along with the
+.LOG file if appropriate. See the manual pages for contact information.
+Your efforts are appreciated.
+Thank you!