diff options
| author | Daniel Mantovani <daniel@gmail.com> | 2019-08-03 16:37:56 -0300 |
|---|---|---|
| committer | Daniel Mantovani <daniel@gmail.com> | 2019-08-03 16:37:56 -0300 |
| commit | 981c3ecf47372c2d236ceba62e4f2da0b95094fc (patch) | |
| tree | ba86ebc0a8071d5cb51b5cd48c6d82e29560ade8 /challenge-019 | |
| parent | 4c2c55fef51a2ddfed57a9b41fe9d94ef0f78c97 (diff) | |
| download | perlweeklychallenge-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.pl | 97 | ||||
| -rw-r--r-- | challenge-019/daniel-mantovani/perl5/ch-2.pl | 61 | ||||
| -rw-r--r-- | challenge-019/daniel-mantovani/perl5/perltidy.LOG | 40 |
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! |
