From d6e42509e43e61d6d4080f4f154c79e6009e81c5 Mon Sep 17 00:00:00 2001 From: Packy Anderson Date: Tue, 25 Jul 2023 00:57:27 -0400 Subject: Challenge 227 solutions in Perl by Packy Anderson --- challenge-227/packy-anderson/README | 27 +++++++++ challenge-227/packy-anderson/perl/task-1.pl | 36 ++++++++++++ challenge-227/packy-anderson/perl/task-2.pl | 79 +++++++++++++++++++++++++++ challenge-227/packy-anderson/task-2-input.txt | 9 +++ 4 files changed, 151 insertions(+) create mode 100755 challenge-227/packy-anderson/perl/task-1.pl create mode 100755 challenge-227/packy-anderson/perl/task-2.pl create mode 100644 challenge-227/packy-anderson/task-2-input.txt diff --git a/challenge-227/packy-anderson/README b/challenge-227/packy-anderson/README index e0f3edaf1e..7c199c42a4 100644 --- a/challenge-227/packy-anderson/README +++ b/challenge-227/packy-anderson/README @@ -3,8 +3,35 @@ ## Perl * [Task 1](perl/task-1.pl) + +Sample output +``` +$ perl/task-1.pl 2023 +Input: $year = 2023 +Output: 2 +``` * [Task 2](perl/task-2.pl) +Sample output +``` +$ perl/task-2.pl < task-2-input.txt +IV + V => IX +M - I => CMXCIX +X / II => V +XI * VI => LXVI +VII ** III => CCCXLIII +V - V => nulla (they knew about zero but didn't have a symbol) +V / II => non potest (they didn't do fractions) +MMM + M => non potest (they only went up to 3999) +V - X => non potest (they didn't do negative numbers) +$ echo "MMMM" | perl/task-2.pl +Lines must be of the form "operand1 operator operand2" +where both operands are valid roman numerals and the +operator is one of the following: + - * / ** +$ echo "X + Y" | perl/task-2.pl +'Y' is not a roman numberal! +``` + ## Raku * [Task 1](raku/task-1.raku) diff --git a/challenge-227/packy-anderson/perl/task-1.pl b/challenge-227/packy-anderson/perl/task-1.pl new file mode 100755 index 0000000000..1bfd2a1d13 --- /dev/null +++ b/challenge-227/packy-anderson/perl/task-1.pl @@ -0,0 +1,36 @@ +#!/usr/bin/env perl +use v5.38; + +# let's use the core modules for date manipulation +use Time::Piece; +use Time::Seconds qw( ONE_DAY ); + +# get the year from the command line +my $year = shift @ARGV + or die "usage: $0 year\n"; + +# do bounds checking as specified in the problem +if ($year < 1753 || $year > 9999) { + die "Only years between 1753 to 9999 are allowed ($year is out of range)\n"; +} + +# create an object for Jan 01 of the given year +my $t = Time::Piece->strptime("$year-01-01", "%Y-%m-%d") + ->truncate(to => 'day'); + +# find the first friday +# in Time::Piece->wday, 1 = Sunday, 6 = Friday +while ( $t->wday != 6) { + $t += ONE_DAY; # add 1 day +} + +# now keep adding 7 days to the date until the year changes, +# noting how many times the day of the month is 13 +my $thirteen_count = 0; +while ( $t->year == $year ) { + $thirteen_count++ if $t->mday == 13; + $t += ONE_DAY * 7; +} + +say "Input: \$year = $year"; +say "Output: $thirteen_count"; \ No newline at end of file diff --git a/challenge-227/packy-anderson/perl/task-2.pl b/challenge-227/packy-anderson/perl/task-2.pl new file mode 100755 index 0000000000..425a4341ea --- /dev/null +++ b/challenge-227/packy-anderson/perl/task-2.pl @@ -0,0 +1,79 @@ +#!/usr/bin/env perl +use v5.38; + +use Roman; # there's a module for handling Roman Numerals! + +sub do_arithmetic { + my $line = shift; + # split the inout line into the three parts: + # the two operands and the infix operator + my($operand1r, $operator, $operand2r) = split /\s+/, $line; + unless (defined $operand1r && + defined $operator && + defined $operand2r) { + say q{Lines must be of the form "operand1 operator operand2"}; + say q{where both operands are valid roman numerals and the}; + say q{operator is one of the following: + - * / **}; + return; + } + + my($operand1a, $operand2a); + + # check that the first operand is a roman numeral + if (isroman($operand1r)) { + # it is a roman numeral, convert it + $operand1a = arabic($operand1r); + } + else { + say "'$operand1r' is not a roman numberal!"; + return; + } + + # check that the second operand is a roman numeral + if (isroman($operand2r)) { + # it is a roman numeral, convert it + $operand2a = arabic($operand2r); + } + else { + say "'$operand2r' is not a roman numberal!"; + return; + } + + # calculate the results + my $result; + if ($operator eq '+') { $result = $operand1a + $operand2a; } + elsif ($operator eq '-') { $result = $operand1a - $operand2a; } + elsif ($operator eq '*') { $result = $operand1a * $operand2a; } + elsif ($operator eq '/') { $result = $operand1a / $operand2a; } + elsif ($operator eq '**') { $result = $operand1a ** $operand2a; } + else { + die "Unknown operator '$operator'; valid operators are + - * / **\n"; + } + + # handle all the special output cases + if ($result == 0) { + say "$operand1r $operator $operand2r => nulla " + . "(they knew about zero but didn't have a symbol)"; + } + elsif (int($result) != $result) { + say "$operand1r $operator $operand2r => non potest " + . "(they didn't do fractions)"; + } + elsif ($result > 3999) { + say "$operand1r $operator $operand2r => non potest " + . "(they only went up to 3999)"; + } + elsif ($result < 0) { + say "$operand1r $operator $operand2r => non potest " + . "(they didn't do negative numbers)"; + } + else { + say "$operand1r $operator $operand2r => " . uc roman($result); + } +} + +# while we have input on STDIN, process the calculations +while (my $line = <>) { + chomp $line; + do_arithmetic($line); +} \ No newline at end of file diff --git a/challenge-227/packy-anderson/task-2-input.txt b/challenge-227/packy-anderson/task-2-input.txt new file mode 100644 index 0000000000..e6e81dde7d --- /dev/null +++ b/challenge-227/packy-anderson/task-2-input.txt @@ -0,0 +1,9 @@ +IV + V +M - I +X / II +XI * VI +VII ** III +V - V +V / II +MMM + M +V - X -- cgit From c66fd873250d3c271ac4ae7649491ca7bf087b41 Mon Sep 17 00:00:00 2001 From: Packy Anderson Date: Tue, 25 Jul 2023 05:24:55 -0400 Subject: Challenge 227 solutions in Raku by Packy Anderson --- challenge-227/packy-anderson/README | 26 +++++++ challenge-227/packy-anderson/raku/task-1.raku | 29 +++++++ challenge-227/packy-anderson/raku/task-2.raku | 106 ++++++++++++++++++++++++++ 3 files changed, 161 insertions(+) create mode 100755 challenge-227/packy-anderson/raku/task-1.raku create mode 100755 challenge-227/packy-anderson/raku/task-2.raku diff --git a/challenge-227/packy-anderson/README b/challenge-227/packy-anderson/README index 7c199c42a4..411d458e93 100644 --- a/challenge-227/packy-anderson/README +++ b/challenge-227/packy-anderson/README @@ -35,4 +35,30 @@ $ echo "X + Y" | perl/task-2.pl ## Raku * [Task 1](raku/task-1.raku) + +Sample output +``` +$ raku/task-1.raku 2023 +Input: $year = 2023 +Output: 2 +``` + * [Task 2](raku/task-2.raku) + +Sample output +``` +$ raku/task-2.raku < task-2-input.txt +IV + V => IX +M - I => CMXCIX +X / II => V +XI * VI => LXVI +VII ** III => CCCXLIII +V - V => nulla (they knew about zero but didn't have a symbol) +V / II => non potest (they didn't do fractions) +MMM + M => non potest (they only went up to 3999) +V - X => non potest (they didn't do negative numbers) +``` + +## Extra + +[task-2-input.txt](task-2-input.txt) \ No newline at end of file diff --git a/challenge-227/packy-anderson/raku/task-1.raku b/challenge-227/packy-anderson/raku/task-1.raku new file mode 100755 index 0000000000..d9fef52c0d --- /dev/null +++ b/challenge-227/packy-anderson/raku/task-1.raku @@ -0,0 +1,29 @@ +#!/usr/bin/env raku + +sub MAIN($year) { + # do bounds checking as specified in the problem + if ($year < 1753 || $year > 9999) { + say "Only years between 1753 to 9999 are allowed ($year is out of range)"; + exit 1; + } + + # create an object for Jan 01 of the given year + my $t = Date.new($year, 1, 1); + + # find the first friday + # in Date.day-of-week, 0 = Sunday, 5 = Friday + while ( $t.day-of-week != 5) { + $t++; # add 1 day + } + + # now keep adding 7 days to the date until the year changes, + # noting how many times the day of the month is 13 + my $thirteen_count = 0; + while ( $t.year == $year ) { + $thirteen_count++ if $t.day == 13; + $t += 7; + } + + say "Input: \$year = $year"; + say "Output: $thirteen_count"; +} \ No newline at end of file diff --git a/challenge-227/packy-anderson/raku/task-2.raku b/challenge-227/packy-anderson/raku/task-2.raku new file mode 100755 index 0000000000..252340956f --- /dev/null +++ b/challenge-227/packy-anderson/raku/task-2.raku @@ -0,0 +1,106 @@ +#!/usr/bin/env raku +use Math::Roman; # it's v0.0.1, but usable + +sub isroman ( $var ) { + # Math::Roman doesn't have a test to see if a string is + # a Roman numeral, but it does throw an exception if it + # cannot convert it + my $result; + try { + CATCH { + default { + return False; + } + } + $result = Math::Roman.new: $var; + } + # Math::Roman also doesn't respect the maximum of 3999 + if ($result.as-arabic > 3999) { + return False; + } + + return True; +} + +sub do_arithmetic (Str $line) { + # split the inout line into the three parts: + # the two operands and the infix operator + my ($operand1, $operator, $operand2) = $line.split(/\s+/); + + unless (defined $operand1 && + defined $operator && + defined $operand2) { + say q{Lines must be of the form "operand1 operator operand2"}; + say q{where both operands are valid roman numerals and the}; + say q{operator is one of the following: + - * / **}; + return; + } + + # check that the first operand is a roman numeral + if (isroman($operand1)) { + # it is a roman numeral, convert it + $operand1 = Math::Roman.new: $operand1; + } + else { + say "'$operand1' is not a roman numberal!"; + return; + } + + # check that the second operand is a roman numeral + if (isroman($operand2)) { + # it is a roman numeral, convert it + $operand2 = Math::Roman.new: $operand2; + } + else { + say "'$operand2' is not a roman numberal!"; + return; + } + + # # calculate the results + my $result; + if ($operator eq '+') { + $result = $operand1.as-arabic + $operand2.as-arabic; + } + elsif ($operator eq '-') { + $result = $operand1.as-arabic - $operand2.as-arabic; + } + elsif ($operator eq '*') { + $result = $operand1.as-arabic * $operand2.as-arabic; + } + elsif ($operator eq '/') { + $result = $operand1.as-arabic / $operand2.as-arabic; + } + elsif ($operator eq '**') { + $result = $operand1.as-arabic ** $operand2.as-arabic; + } + else { + die "Unknown operator '$operator'; valid operators are + - * / **\n"; + } + + # handle all the special output cases + if ($result == 0) { + say "$operand1 $operator $operand2 => nulla " + ~ "(they knew about zero but didn't have a symbol)"; + } + elsif ($result.truncate != $result) { + say "$operand1 $operator $operand2 => non potest " + ~ "(they didn't do fractions)"; + } + elsif ($result > 3999) { + say "$operand1 $operator $operand2 => non potest " + ~ "(they only went up to 3999)"; + } + elsif ($result < 0) { + say "$operand1 $operator $operand2 => non potest " + ~ "(they didn't do negative numbers)"; + } + else { + $result = Math::Roman.new: value => $result.Int; + say "$operand1 $operator $operand2 => $result"; + } +} + +# while we have input on STDIN, process the calculations +for $*IN.lines -> $line { + do_arithmetic($line); +} \ No newline at end of file -- cgit From ab5a2fbe099db9164d6f77170e775ab8183602bc Mon Sep 17 00:00:00 2001 From: Packy Anderson Date: Wed, 26 Jul 2023 18:32:14 -0400 Subject: Blog about last week's challenge --- challenge-226/packy-anderson/README | 3 +++ 1 file changed, 3 insertions(+) diff --git a/challenge-226/packy-anderson/README b/challenge-226/packy-anderson/README index e0f3edaf1e..50e31830b9 100644 --- a/challenge-226/packy-anderson/README +++ b/challenge-226/packy-anderson/README @@ -9,3 +9,6 @@ * [Task 1](raku/task-1.raku) * [Task 2](raku/task-2.raku) + +## Blog Post +* [Perl Weekly Challenge 226](http://packy.dardan.com/2023/07/26/perl-weekly-challenge-226/) \ No newline at end of file -- cgit From a0e6853dbbd46409862ca090f096f9253a8e0a13 Mon Sep 17 00:00:00 2001 From: Packy Anderson Date: Thu, 27 Jul 2023 01:41:52 -0400 Subject: Blog about this week's challenge --- challenge-227/packy-anderson/README | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/challenge-227/packy-anderson/README b/challenge-227/packy-anderson/README index 411d458e93..1b230ba294 100644 --- a/challenge-227/packy-anderson/README +++ b/challenge-227/packy-anderson/README @@ -59,6 +59,10 @@ MMM + M => non potest (they only went up to 3999) V - X => non potest (they didn't do negative numbers) ``` -## Extra +## Data File -[task-2-input.txt](task-2-input.txt) \ No newline at end of file +[task-2-input.txt](task-2-input.txt) + +## Blog Post + +[Perl Weekly Challenge 227](http://packy.dardan.com/2023/07/27/perl-weekly-challenge-227/) \ No newline at end of file -- cgit