diff options
| -rw-r--r-- | challenge-226/packy-anderson/README | 3 | ||||
| -rw-r--r-- | challenge-227/packy-anderson/README | 57 | ||||
| -rwxr-xr-x | challenge-227/packy-anderson/perl/task-1.pl | 36 | ||||
| -rwxr-xr-x | challenge-227/packy-anderson/perl/task-2.pl | 79 | ||||
| -rwxr-xr-x | challenge-227/packy-anderson/raku/task-1.raku | 29 | ||||
| -rwxr-xr-x | challenge-227/packy-anderson/raku/task-2.raku | 106 | ||||
| -rw-r--r-- | challenge-227/packy-anderson/task-2-input.txt | 9 |
7 files changed, 319 insertions, 0 deletions
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 diff --git a/challenge-227/packy-anderson/README b/challenge-227/packy-anderson/README index e0f3edaf1e..1b230ba294 100644 --- a/challenge-227/packy-anderson/README +++ b/challenge-227/packy-anderson/README @@ -3,9 +3,66 @@ ## 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) + +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) +``` + +## Data 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 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/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 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 |
