aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2023-07-28 11:04:33 +0100
committerGitHub <noreply@github.com>2023-07-28 11:04:33 +0100
commit0961dc37468d211b77f2dced2eb5cd9acf9649c0 (patch)
tree20ca2b2d64f32b35aa41d2632e514ffe79b4f908
parente72ccc8528077ed10b882d93be08dbc521c6ed29 (diff)
parenta0e6853dbbd46409862ca090f096f9253a8e0a13 (diff)
downloadperlweeklychallenge-club-0961dc37468d211b77f2dced2eb5cd9acf9649c0.tar.gz
perlweeklychallenge-club-0961dc37468d211b77f2dced2eb5cd9acf9649c0.tar.bz2
perlweeklychallenge-club-0961dc37468d211b77f2dced2eb5cd9acf9649c0.zip
Merge pull request #8450 from packy/master
Challenge 227 solutions by Packy Anderson
-rw-r--r--challenge-226/packy-anderson/README3
-rw-r--r--challenge-227/packy-anderson/README57
-rwxr-xr-xchallenge-227/packy-anderson/perl/task-1.pl36
-rwxr-xr-xchallenge-227/packy-anderson/perl/task-2.pl79
-rwxr-xr-xchallenge-227/packy-anderson/raku/task-1.raku29
-rwxr-xr-xchallenge-227/packy-anderson/raku/task-2.raku106
-rw-r--r--challenge-227/packy-anderson/task-2-input.txt9
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