diff options
| author | Mohammad Sajid Anwar <Mohammad.Anwar@yahoo.com> | 2025-06-23 00:30:14 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-23 00:30:14 +0100 |
| commit | 5b52e6a2dac00024ac5ba597b05a16de794a87f3 (patch) | |
| tree | 18d1d6923ca20064dc0f3a5a0236e6b944c46748 | |
| parent | 7f9694c558d5879dccdc5ef4e0318f30fc33e508 (diff) | |
| parent | 1a187b4873288f30fc2279c93da9085a663efda5 (diff) | |
| download | perlweeklychallenge-club-5b52e6a2dac00024ac5ba597b05a16de794a87f3.tar.gz perlweeklychallenge-club-5b52e6a2dac00024ac5ba597b05a16de794a87f3.tar.bz2 perlweeklychallenge-club-5b52e6a2dac00024ac5ba597b05a16de794a87f3.zip | |
Merge pull request #12212 from robbie-hatley/rh326
Robbie Hatley's solutions, in Perl, for The Weekly Challenge #326.
| -rw-r--r-- | challenge-326/robbie-hatley/blog.txt | 1 | ||||
| -rwxr-xr-x | challenge-326/robbie-hatley/perl/ch-1.pl | 109 | ||||
| -rwxr-xr-x | challenge-326/robbie-hatley/perl/ch-2.pl | 93 |
3 files changed, 203 insertions, 0 deletions
diff --git a/challenge-326/robbie-hatley/blog.txt b/challenge-326/robbie-hatley/blog.txt new file mode 100644 index 0000000000..b89a61eecf --- /dev/null +++ b/challenge-326/robbie-hatley/blog.txt @@ -0,0 +1 @@ +https://hatley-software.blogspot.com/2025/06/robbie-hatleys-solutions-in-perl-for_21.html
\ No newline at end of file diff --git a/challenge-326/robbie-hatley/perl/ch-1.pl b/challenge-326/robbie-hatley/perl/ch-1.pl new file mode 100755 index 0000000000..1f32e60dd4 --- /dev/null +++ b/challenge-326/robbie-hatley/perl/ch-1.pl @@ -0,0 +1,109 @@ +#!/usr/bin/env perl + +=pod + +-------------------------------------------------------------------------------------------------------------- +TITLE AND ATTRIBUTION: +Solutions in Perl for The Weekly Challenge 326-1, +written by Robbie Hatley on Sat Jun 21, 2025. + +-------------------------------------------------------------------------------------------------------------- +PROBLEM DESCRIPTION: +Task 326-1: Day of the Year +Submitted by: Mohammad Sajid Anwar +You are given a date in the format YYYY-MM-DD. Write a script to +find day number of the year that the given date represent. + +Example #1: +Input: $date = '2025-02-02' +Output: 33 + +Example #2: +Input: $date = '2025-04-10' +Output: 100 + +Example #3: +Input: $date = '2025-09-07' +Output: 250 + +-------------------------------------------------------------------------------------------------------------- +PROBLEM NOTES: +To solve this problem, I wrote subs to extract (year, month, day) from strings, check strings for validity, +determine whether a given year is a leap year, determine the number of days in a given month in a given year, +and return day-of-year. This solution is thus more "structured" than most of my PWCC solutions. Using five +subroutines instead of cramming everything into one makes the code easier to read, understand, and maintain. + +-------------------------------------------------------------------------------------------------------------- +IO NOTES: +Input is via either built-in variables or via @ARGV. If using @ARGV, provide one argument which must be a +single-quoted array of double-quoted date strings, "YYYY-MM-DD", in proper Perl syntax, like so: +./ch-1.pl '("rat", "2025-11-13", "2025-11-88")' + +Output is to STDOUT and will be each input followed by the corresponding output. + +=cut + +# ------------------------------------------------------------------------------------------------------------ +# PRAGMAS, MODULES, AND SUBS: + +use v5.36; +use utf8::all; + + # Get year, month, and day numbers from date string: + sub ymd ($string) { + my $y = 0 + substr($string, 0, 4); + my $m = 0 + substr($string, 5, 2); + my $d = 0 + substr($string, 8, 2); + return ($y, $m, $d)} + + # Is a given date string valid? + sub is_valid ($string) { + return 0 if $string !~ m/^\d\d\d\d-\d\d-\d\d$/; + my ($y, $m, $d) = ymd($string); + return 0 if $m < 1 || $m > 12; + return 0 if $d < 1 || $d > 31; + return 1} + + # Is a given year a leap year? + sub is_leap_year ($year) { + # Gregorian Calendar: + if ( 0 == $year%4 && 0 != $year%100 ) {return 1} + elsif ( 0 == $year%400 ) {return 1} + else {return 0}} + + # How many days are in a given month of a given year? + sub dpm ($year, $month) { + state @dpm = (0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); + if ( 2 == $month ) { return (is_leap_year($year) ? 29 : 28)} + else {return $dpm[$month]}} + + # What is the day-of-year for a given date string? + sub day_of_year ($string) { + my ($y, $m, $d) = ymd($string); # Get year, month, day from string. + my $ily = is_leap_year($y); # Is this a leap year? + my $count = 0; # Make and initialize a day counter. + for my $month (1..$m) { # For each month from Jan to current: + if ($month < $m) { # If month isless than current, + $count += dpm($y, $month)} # add month's days-per-month to counter. + else { # Otherwise, + $count += $d}} # add current day to counter. + return $count} # Return count. + +# ------------------------------------------------------------------------------------------------------------ +# INPUTS: +my @strings = @ARGV ? eval($ARGV[0]) : ("2025-02-02", "2025-04-10", "2025-09-07"); +# Expected outputs : 33 100 250 + +# ------------------------------------------------------------------------------------------------------------ +# MAIN BODY OF PROGRAM: +$"=', '; +for my $string (@strings) { + say ''; + say "String = $string"; + if (!is_valid($string)) { + say "Error: invalid string."; + next; + } + my $doy = day_of_year($string); + say "Day of year = $doy"; +} diff --git a/challenge-326/robbie-hatley/perl/ch-2.pl b/challenge-326/robbie-hatley/perl/ch-2.pl new file mode 100755 index 0000000000..b8b1468a63 --- /dev/null +++ b/challenge-326/robbie-hatley/perl/ch-2.pl @@ -0,0 +1,93 @@ +#!/usr/bin/env perl + +=pod + +-------------------------------------------------------------------------------------------------------------- +TITLE AND ATTRIBUTION: +Solutions in Perl for The Weekly Challenge 326-2, +written by Robbie Hatley on Sat Jun 21, 2025. + +-------------------------------------------------------------------------------------------------------------- +PROBLEM DESCRIPTION: +Task 326-2: Decompressed List +Submitted by: Mohammad Sajid Anwar +You are given an array of positive integers having an even number +of elements. Write a script to to return the decompressed list. +To decompress, pick adjacent pair (i, j) and replace it with j, +i times. + +Example #1: +Input: @ints = (1, 3, 2, 4) +Output: (3, 4, 4) +Pair 1: (1, 3) => 3 one time => (3) +Pair 2: (2, 4) => 4 two times => (4, 4) + +Example #2: +Input: @ints = (1, 1, 2, 2) +Output: (1, 2, 2) +Pair 1: (1, 1) => 1 one time => (1) +Pair 2: (2, 2) => 2 two times => (2, 2) + +Example #3: +Input: @ints = (3, 1, 3, 2) +Output: (1, 1, 1, 2, 2, 2) +Pair 1: (3, 1) => 1 three times => (1, 1, 1) +Pair 2: (3, 2) => 2 three times => (2, 2, 2) + +-------------------------------------------------------------------------------------------------------------- +PROBLEM NOTES: +To solve this problem, I wrote two subs: one to check input for validity, and one to "decompress" an array +as described in the problem description. For a change, this "task 2" is easier than the corresponding Task 1; +I needed 5 subroutines for that one. + +-------------------------------------------------------------------------------------------------------------- +IO NOTES: +Input is via either built-in variables or via @ARGV. If using @ARGV, provide one argument which must be a +single-quoted array of non-empty even-size arrays positive integers, in proper Perl syntax, like so: +./ch-2.pl '([5,1,3,4],[2,3,4,29,15,40])' + +Output is to STDOUT and will be each input followed by the corresponding output. + +=cut + +# ------------------------------------------------------------------------------------------------------------ +# PRAGMAS, MODULES, AND SUBS: + + use v5.36; + use utf8::all; + + # Is a given scalar a reference to a non-empty even-sized array of positive integers? + sub is_array_of_even_pos_ints ($aref) { + return 0 unless 'ARRAY' eq ref $aref; # Return 0 if $aref isn't a ref to an array. + return 0 unless scalar(@$aref) > 0; # Return 0 if the array is empty. + return 0 unless 0 == scalar(@$aref) % 2; # Return 0 if the array has odd size. + for my $item (@$aref) { # For each item in array, + return 0 if $item !~ m/^[1-9]\d*$/} # return 0 if item is not a positive integer. + return 1} # is ref to non-empty even-size array of positive integers + + # Decompress an array: + sub decompress ($aref) { + my @c = @$aref; # Compressed array. + my @d = (); # Decompressed array. + for my $idx (0..scalar(@c)/2-1){ # For each pair of items in comp. array, + push @d, ($c[$idx*2+1])x$c[$idx*2]} # tack second-item copies of first item to decomp. array. + return @d} # Return decompressed array. + +# ------------------------------------------------------------------------------------------------------------ +# INPUTS: +my @arrays = @ARGV ? eval($ARGV[0]) : ([1, 3, 2, 4], [1, 1, 2, 2], [3, 1, 3, 2]); +# Expected outputs : (3, 4, 4) (1, 2, 2) (1, 1, 1, 2, 2, 2) + +# ------------------------------------------------------------------------------------------------------------ +# MAIN BODY OF PROGRAM: +$"=', '; +for my $aref (@arrays) { + say ''; + say "Compressed array = (@$aref)"; + if (!is_array_of_even_pos_ints($aref)) { + say "Error: not a non-empty even-size array of positive integers."; + next; + } + my @d = decompress($aref); + say "Decompressed array = (@d)"; +} |
