aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2021-02-19 05:47:01 +0000
committerGitHub <noreply@github.com>2021-02-19 05:47:01 +0000
commitcac57e99701c85e3604e838829d042730d478329 (patch)
tree27ebaf632d581a7c0f4d1019d2fec476e22c7a7d
parentde8b2e2b5b619235cb149d7871b75cfab93cbfe2 (diff)
parentc91195bb834b740c54cbd0073961f443bacf4f0e (diff)
downloadperlweeklychallenge-club-cac57e99701c85e3604e838829d042730d478329.tar.gz
perlweeklychallenge-club-cac57e99701c85e3604e838829d042730d478329.tar.bz2
perlweeklychallenge-club-cac57e99701c85e3604e838829d042730d478329.zip
Merge pull request #3568 from Abigail/abigail/week-100
Abigail/week 100
-rw-r--r--challenge-100/abigail/README.md134
-rw-r--r--challenge-100/abigail/awk/ch-1.gawk21
-rw-r--r--challenge-100/abigail/awk/ch-2.awk35
-rw-r--r--challenge-100/abigail/bash/ch-1.sh56
-rw-r--r--challenge-100/abigail/bash/ch-2.sh63
-rw-r--r--challenge-100/abigail/befunge-93/ch-1.bf9315
-rw-r--r--challenge-100/abigail/c/ch-1.c75
-rw-r--r--challenge-100/abigail/c/ch-2.c53
-rw-r--r--challenge-100/abigail/lua/ch-1.lua56
-rw-r--r--challenge-100/abigail/lua/ch-2.lua41
-rw-r--r--challenge-100/abigail/node/ch-1.js32
-rw-r--r--challenge-100/abigail/node/ch-2.js27
-rw-r--r--challenge-100/abigail/perl/ch-1.pl41
-rw-r--r--challenge-100/abigail/perl/ch-2.pl32
-rw-r--r--challenge-100/abigail/python/ch-1.py50
-rw-r--r--challenge-100/abigail/python/ch-2.py36
-rw-r--r--challenge-100/abigail/ruby/ch-1.rb43
-rw-r--r--challenge-100/abigail/ruby/ch-2.rb35
-rw-r--r--challenge-100/abigail/t/ctest.ini11
-rw-r--r--challenge-100/abigail/t/input-1-12
-rw-r--r--challenge-100/abigail/t/input-1-224
-rw-r--r--challenge-100/abigail/t/input-1-324
-rw-r--r--challenge-100/abigail/t/input-2-14
-rw-r--r--challenge-100/abigail/t/input-2-24
-rw-r--r--challenge-100/abigail/t/output-1-1.exp2
-rw-r--r--challenge-100/abigail/t/output-1-2.exp24
-rw-r--r--challenge-100/abigail/t/output-1-3.exp24
-rw-r--r--challenge-100/abigail/t/output-2-1.exp1
-rw-r--r--challenge-100/abigail/t/output-2-2.exp1
29 files changed, 891 insertions, 75 deletions
diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md
index 56e481bb08..e55419aae3 100644
--- a/challenge-100/abigail/README.md
+++ b/challenge-100/abigail/README.md
@@ -1,110 +1,94 @@
# Solution by Abigail
-## [Read N-characters](https://perlweeklychallenge.org/blog/perl-weekly-challenge-098/#TASK1)
+## [Fun Time](https://perlweeklychallenge.org/blog/perl-weekly-challenge-100/#TASK1)
-You are given file `$FILE`.
+You are given a time (12 hour / 24 hour).
-Create subroutine `readN($FILE, $number)` returns the first `n`-characters
-and moves the pointer to the (`n+1`)th character.
+Write a script to convert the given time from 12 hour format to 24
+hour format and vice versa.
-### Notes
+Ideally we expect a one-liner.
-What a poorly defined challenge.
-
-> You are given a file
-
-What does that mean? Do we get the content? A file handle?
-A file descriptor? A file name?
-
-The example (but not the challenge itself), suggest we're getting
-a file name. Ok, but....:
-
-> moves the pointer
-
-What pointer? File handles/descriptors point to something, so
-then it can be argued we should leave the file handle open,
-pointing to a place in the file. But we have just established we
-are *not getting* a file handle -- we're getting a file name.
-So, what pointer are we talking about?
-
-What on earth are we supposed to do?
-
-Are we supposed to create a file handle, and keep file handle open?
-Should we just slurp in the file content, and keep a pointer
-to what we have returned?
-
-What should happen if we call `readN` with different files, interleaved?
-Keep track of where we are for each file? Restart if called with `file1`,
-then `file2`, and then `file1` again?
-
-Our implementation will be a real stab in the dark -- we've no idea what
-we are supposed to do.
-
-### Input
-Our program will read lines from standard input; each line consists
-of a filename and an amount of characters to read, separated by whitespace.
-
-### Example
+### Examples
~~~~
-Input: Suppose the file (input.txt) contains "1234567890"
-Output:
- print readN("input.txt", 4); # returns "1234"
- print readN("input.txt", 4); # returns "5678"
- print readN("input.txt", 4); # returns "90"
+Input: 05:15 pm or 05:15pm
+Output: 17:15
+
+Input: 19:15
+Output: 07:15 pm or 07:15pm
~~~~
### Solutions
-* [AWK](awk/ch-1.awk)
+* [GNU AWK](awk/ch-1.gawk)
* [Bash](bash/ch-1.sh)
-* [C](c/ch-1.ch)
+* [Befunge-93](befunge-93/ch-1.bf93)
+* [C](c/ch-1.c)
+* [Lua](lua/ch-1.lua)
+* [Node.js](node/ch-1.js)
* [Perl](perl/ch-1.pl)
+* [Python](python/ch-1.py)
+* [Ruby](ruby/ch-1.rb)
### Blog
-## [Search Insert Position](https://perlweeklychallenge.org/blog/perl-weekly-challenge-098/#TASK2)
+## [Triangle Sum](https://perlweeklychallenge.org/blog/perl-weekly-challenge-100/#TASK2)
+
+You are given triangle array.
-You are given a sorted array of distinct integers `@N` and a target `$N`.
+Write a script to find the minimum path sum from top to bottom.
-Write a script to return the index of the given target if found
-otherwise place the target in the sorted array and return the index.
+When you are on index `i` on the current row then you may move to
+either index `i` or index `i + 1` on the next row.
### Examples
#### Example 1
~~~~
-Input: @N = (1, 2, 3, 4) and $N = 3
-Output: 2 since the target 3 is in the array at the index 2.
+Input: Triangle = [ [1], [2,4], [6,4,9], [5,1,7,2] ]
+Output: 8
+
+Explanation: The given triangle
+
+ 1
+ 2 4
+ 6 4 9
+ 5 1 7 2
+
+The minimum path sum from top to bottom: 1 + 2 + 4 + 1 = 8
+
+ [1]
+ [2] 4
+ 6 [4] 9
+ 5 [1] 7 2
~~~~
#### Example 2
~~~~
-Input: @N = (1, 3, 5, 7) and $N = 6
-Output: 3 since the target 6 is missing and should be placed at the index 3.
-~~~~
+Input: Triangle = [ [3], [3,1], [5,2,3], [4,3,1,3] ]
+Output: 7
-#### Example 3
-~~~~
-Input: @N = (12, 14, 16, 18) and $N = 10
-Output: 0 since the target 10 is missing and should be placed at the index 0.
-~~~~
+Explanation: The given triangle
-#### Example 4
-~~~~
-Input: @N = (11, 13, 15, 17) and $N = 19
-Output: 4 since the target 19 is missing and should be placed at the index 4.
-~~~~
+ 3
+ 3 1
+ 5 2 3
+ 4 3 1 3
-### Notes
-We could write a binary search to find the target number in the
-array. This is tempting, as a binary search take O (log N). But
-this is futile. We're also asked to add the target element to the
-array (if not found), and adding an element in the middle of an
-array takes linear time. So, worst case, we're already spending
-linear time. (And to read the array, we're spending linear time
-anyway).
+The minimum path sum from top to bottom: 3 + 1 + 2 + 1 = 7
+ [3]
+ 3 [1]
+ 5 [2] 3
+ 4 3 [1] 3
+~~~~
### Solutions
+* [AWK](awk/ch-2.awk)
* [Bash](bash/ch-2.sh)
+* [C](c/ch-2.c)
+* [Lua](lua/ch-2.lua)
+* [Node.js](node/ch-2.js)
* [Perl](perl/ch-2.pl)
+* [Python](python/ch-2.py)
+* [Ruby](ruby/ch-2.rb)
### Blog
diff --git a/challenge-100/abigail/awk/ch-1.gawk b/challenge-100/abigail/awk/ch-1.gawk
new file mode 100644
index 0000000000..9ad484bbc6
--- /dev/null
+++ b/challenge-100/abigail/awk/ch-1.gawk
@@ -0,0 +1,21 @@
+#!/opt/local/bin/gawk
+
+#
+# See ../README.md
+#
+
+#
+# Run as: gawk -f ch-1.gawk < input-file
+# This must be run as GNU AWK.
+#
+
+
+{
+ match ($0, /^([0-9]?[0-9]):([0-9][0-9])([AaPp]?)m?/, parts);
+ printf "%02d:%02d%s\n", \
+ parts [3] ? (parts [1] % 12) + (parts [3] == "a" ? 0 : 12) \
+ : (parts [1] % 12) ? (parts [1] % 12) : 12, \
+ parts [2], \
+ parts [3] ? "" \
+ : parts [1] >= 12 ? "pm" : "am"
+}
diff --git a/challenge-100/abigail/awk/ch-2.awk b/challenge-100/abigail/awk/ch-2.awk
new file mode 100644
index 0000000000..c34241052d
--- /dev/null
+++ b/challenge-100/abigail/awk/ch-2.awk
@@ -0,0 +1,35 @@
+#!/usr/bin/awk
+
+#
+# See ../README.md
+#
+
+#
+# Run as: awk -f ch-2.awk < input-file
+#
+
+#
+# Read in the triangle
+#
+{
+ for (i = 1; i <= NF; i ++) {
+ nums [NR, i] = $i
+ }
+}
+
+#
+# Calculate the minimum path bottom to top
+#
+END {
+ for (x = NR - 1; x >= 0; x --) {
+ for (y = 1; y <= x; y ++) {
+ if (nums [x + 1, y] < nums [x + 1, y + 1]) {
+ nums [x, y] += nums [x + 1, y]
+ }
+ else {
+ nums [x, y] += nums [x + 1, y + 1]
+ }
+ }
+ }
+ print nums [1, 1]
+}
diff --git a/challenge-100/abigail/bash/ch-1.sh b/challenge-100/abigail/bash/ch-1.sh
new file mode 100644
index 0000000000..f541148f6d
--- /dev/null
+++ b/challenge-100/abigail/bash/ch-1.sh
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+#
+# See ../README.md
+#
+
+#
+# Run as: bash ch-1.sh < input-file
+#
+
+while read time
+do #
+ # Extract the parts from the input.
+ #
+ ampm=${time//[0-9:]}
+ hour=${time/:*}
+ minutes=${time/*:}
+ minutes=${minutes/[ap]m}
+
+ #
+ # We cannot have a leading 0 for "08" and "09", as
+ # a number starting with a 0 in $(( )) expansion
+ # is considered an octal number. For 00 .. 07, this
+ # is fine. But 08 and 09 given an error.
+ #
+ if [ "$hour" == "08" ]
+ then hour=8
+ fi
+ if [ "$hour" == "09" ]
+ then hour=9
+ fi
+
+ #
+ # Do the calculations.
+ #
+ if [ "$ampm" == "am" ]
+ then hour=$((hour == 12 ? 0 : hour))
+ new_ampm=""
+ fi
+ if [ "$ampm" == "pm" ]
+ then hour=$((hour == 12 ? 12 : hour + 12))
+ new_ampm=""
+ fi
+ if [ "$ampm" == "" ]
+ then if [ $hour -ge 12 ]
+ then new_ampm="pm"
+ else new_ampm="am"
+ fi
+ hour=$((hour % 12 == 0 ? 12 : hour % 12))
+ fi
+
+ #
+ # And print the results.
+ #
+ printf "%02d:%02d%s\n" $hour $minutes $new_ampm
+done
diff --git a/challenge-100/abigail/bash/ch-2.sh b/challenge-100/abigail/bash/ch-2.sh
new file mode 100644
index 0000000000..c38e51eef0
--- /dev/null
+++ b/challenge-100/abigail/bash/ch-2.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+#
+# See ../README.md
+#
+
+#
+# Run as: bash ch-2.sh < input-file
+#
+
+set -f
+
+#
+# Bash only has one-dimensional arrays, so we're using a function
+# to map 2-d indices to a 1-d index.
+#
+# Note also that we can only return numbers 0 - 255 as "return" values
+# (by hijacking the return status), which isn't good enough for us,
+# so we use the global variable "index" to pass the result back.
+#
+
+function idx () {
+ local x=$1
+ local y=$2
+ index=$((x * (x + 1) / 2 + y))
+}
+
+#
+# Read in the data: we can read a line at the time, and have
+# it split on white space, giving use an array of numbers in "row".
+# We iterate over the row, mapping the x, y coordinates to a
+# single index, and storing the result in the array "numbers".
+#
+
+x=0
+while read -a row
+do for ((y = 0; y < ${#row[*]}; y ++))
+ do idx $x $y
+ numbers[$index]=${row[$y]}
+ done
+ x=$((x + 1))
+done
+
+#
+# Work bottom to top to calculate the minimum path.
+#
+for ((r = $x - 2; r >= 0; r --))
+do for ((y = 0; y <= $r; y ++))
+ do idx $((r + 1)) $y
+ val1=${numbers[$index]}
+ idx $((r + 1)) $((y + 1))
+ val2=${numbers[$index]}
+ min=$((val1 < val2 ? val1 : val2))
+ idx $r $y
+ numbers[$index]=$((numbers[$index] + $min))
+ done
+done
+
+
+#
+# Print the result.
+#
+echo ${numbers[0]}
diff --git a/challenge-100/abigail/befunge-93/ch-1.bf93 b/challenge-100/abigail/befunge-93/ch-1.bf93
new file mode 100644
index 0000000000..180760e6f6
--- /dev/null
+++ b/challenge-100/abigail/befunge-93/ch-1.bf93
@@ -0,0 +1,15 @@
+>022p&:1+!#@_~$&\> ~:" "-!#v_:"a"-!#v_:"p"-!#v_$v
+,>"m"v ^ < :
+*, , 5
+2^_ v v _v#-*34: $$$~~ < 6
+5 : v 0$< v +#< <
+^ g# < v < ` % +
+ 2 v_v+ 6
+ 2 v*34$< " "6 6
+ ^.<_0.v v _^#-*38: ++66 $$$~~ < p a6 $
+ ^`# < : " "^_^
+ * 3 >v< %
+ 3 3 2 +
+ 3 * 2 6
+ : v`# < p 6
+ ^,":".<_0.^ >: ^
diff --git a/challenge-100/abigail/c/ch-1.c b/challenge-100/abigail/c/ch-1.c
new file mode 100644
index 0000000000..8ea41facc9
--- /dev/null
+++ b/challenge-100/abigail/c/ch-1.c
@@ -0,0 +1,75 @@
+# include <stdlib.h>
+# include <stdio.h>
+# include <string.h>
+# include <ctype.h>
+
+/*
+ * See ../README.md
+ */
+
+/*
+ * Run as: cc -o ch-1.o ch-1.c; ./ch-1.o < input-file
+ */
+
+int main (void) {
+ char * line = NULL;
+ size_t len = 0;
+ size_t str_len;
+
+ while ((str_len = getline (&line, &len, stdin)) != -1) {
+ char * ptr = line;
+
+ /*
+ * Parse hour and minute from line
+ */
+ int hour = atoi (ptr);
+ while (isdigit (* ptr)) {
+ ptr ++;
+ }
+ ptr ++; /* The ':' separating hour and minute */
+ int minute = atoi (ptr);
+
+ /*
+ * Advance the pointer to the first character of the
+ * AM/PM marker; if there is none, it will point
+ * to the NUL byte. (And * ptr is then false).
+ */
+ while (* ptr && (isdigit (* ptr) || isspace (* ptr))) {
+ ptr ++;
+ }
+
+ /*
+ * Calculate the new AM/PM marker:
+ * - If there was one, there new one will be empty.
+ * - Else, if the hour is 12 or larger, it's PM
+ * - Else, it's AM
+ */
+ char * new_ampm = * ptr ? "" : hour >= 12 ? "pm" : "am";
+
+ /*
+ * Calculate the new hour:
+ * - we always mod the hour by 12;
+ * this has the effect of making 12 AM (and 12 PM)
+ * equal to 0, and subtracts 12 from time in 24-hour
+ * format, for times after noon.
+ * - if we started from a 24 hour time, and the hour is
+ * now 0, make it 12.
+ * - if we started from PM time, add 12 to the hour.
+ */
+ hour %= 12;
+ if (!* ptr && hour == 0) {
+ hour = 12;
+ }
+ if (tolower (* ptr) == 'p') {
+ hour += 12;
+ }
+
+ /*
+ * Print the result.
+ */
+ printf ("%02d:%02d%s\n", hour, minute, new_ampm);
+ }
+ free (line);
+
+ return (0);
+}
diff --git a/challenge-100/abigail/c/ch-2.c b/challenge-100/abigail/c/ch-2.c
new file mode 100644
index 0000000000..c22c163024
--- /dev/null
+++ b/challenge-100/abigail/c/ch-2.c
@@ -0,0 +1,53 @@
+# include <stdlib.h>
+# include <stdio.h>
+# include <string.h>
+# include <math.h>
+
+/*
+ * See ../README.md
+ */
+
+/*
+ * Run as: cc -o ch-2.o ch-2.c; ./ch-2.o < input-file
+ */
+
+size_t idx (size_t x, size_t y) {
+ return (x * (x + 1)) / 2 + y;
+}
+
+int main (void) {
+ long long number;
+ long long * numbers = NULL;
+ size_t nr_of_numbers = 0;
+
+ while (scanf ("%lld ", &number) != EOF) {
+ if ((numbers = (long long *)
+ realloc (numbers,
+ ++ nr_of_numbers * sizeof (long long *))) == NULL) {
+ perror (NULL);
+ exit (1);
+ }
+ numbers [nr_of_numbers - 1] = number;
+ }
+
+ /*
+ * Calculate the max row number from the max index
+ */
+ size_t max_row = (size_t) ((sqrt (9 + 8 * nr_of_numbers) - 3) / 2);
+
+
+ /*
+ * Calculate the minimum path bottom to top.
+ */
+ for (ssize_t x = max_row - 1; x >= 0; x --) {
+ for (size_t y = 0; y <= x; y ++) {
+ size_t idx1 = idx (x, y);
+ size_t idx2 = idx (x + 1, y);
+ size_t idx3 = idx (x + 1, y + 1);
+ numbers [idx1] += numbers [idx2] < numbers [idx3]
+ ? numbers [idx2] : numbers [idx3];
+ }
+ }
+
+ printf ("%lld\n", numbers [0]);
+}
diff --git a/challenge-100/abigail/lua/ch-1.lua b/challenge-100/abigail/lua/ch-1.lua
new file mode 100644
index 0000000000..6e0f3a721a
--- /dev/null
+++ b/challenge-100/abigail/lua/ch-1.lua
@@ -0,0 +1,56 @@
+#!/opt/local/bin/lua
+
+--
+-- See ../README.md
+--
+
+--
+-- Run as: lua ch-1.lua < input-file
+--
+
+for line in io . lines () do
+ --
+ -- Parse input
+ --
+ local _, _, hour, minute, ampm = line : find ("(%d+):(%d+)%s*([ap]?)m?")
+
+ --
+ -- We need an explicite case to numbers
+ --
+ hour = tonumber (hour)
+ minute = tonumber (minute)
+
+ --
+ -- Find out what the new AM/PM marker should be:
+ -- - If the current marker is AM or PM, the new one is empty.
+ -- - Else, if the hour is 12 or higher, it's PM
+ -- - Else, it's AM
+ --
+ local new_ampm = ""
+ if ampm == ""
+ then if hour >= 12
+ then new_ampm = "pm"
+ else new_ampm = "am"
+ end
+ end
+
+ --
+ -- Calculate the new hours
+ -- - If AM, an hour of 12 becomes 0, and we leave the rest as is
+ -- - If PM, an hour of 12 stays 12, else, we add 12 to the hour
+ -- - If no AM/PM, subtract 12 if the hour is larger than 12;
+ -- add 12 if the hour is 0
+ --
+ hour = hour % 12
+ if ampm == "" and hour == 0
+ then hour = 12
+ end
+ if ampm == "p"
+ then hour = hour + 12
+ end
+
+ --
+ -- Print the results
+ --
+ print (string . format ("%02d:%02d%s", hour, minute, new_ampm))
+end
diff --git a/challenge-100/abigail/lua/ch-2.lua b/challenge-100/abigail/lua/ch-2.lua
new file mode 100644
index 0000000000..d3e3b3b1d1
--- /dev/null
+++ b/challenge-100/abigail/lua/ch-2.lua
@@ -0,0 +1,41 @@
+#!/opt/local/bin/lua
+
+--
+-- See ../README.md
+--
+
+--
+-- Run as: lua ch-2.lua < input-file
+--
+
+local numbers = {}
+
+--
+-- Read in the data
+--
+for line in io . lines () do
+ local row = {}
+ for n in line : gsub ("\n", "") : gmatch ("-?%d+") do
+ table . insert (row, n)
+ end
+ table . insert (numbers, row)
+end
+
+--
+-- Calculate minimum path, bottom to top
+--
+for x = #numbers - 1, 1, -1 do
+ local row = numbers [x]
+ for y = 1, #row do
+ min = numbers [x + 1] [y]
+ if numbers [x + 1] [y + 1] < min
+ then min = numbers [x + 1] [y + 1]
+ end
+ numbers [x] [y] = numbers [x] [y] + min
+ end
+end
+
+--
+-- Print result
+--
+print (numbers [1] [1])
diff --git a/challenge-100/abigail/node/ch-1.js b/challenge-100/abigail/node/ch-1.js
new file mode 100644
index 0000000000..d513e691e1
--- /dev/null
+++ b/challenge-100/abigail/node/ch-1.js
@@ -0,0 +1,32 @@
+#!/usr/local/bin/node
+
+//
+// See ../README.md
+//
+
+//
+// Run as: node ch-1.js < input-file
+//
+
+let printf = require ("printf")
+
+require ('readline')
+. createInterface ({input: process . stdin})
+. on ('line', _ => {
+ //
+ // Parse data
+ //
+ let [m, hour, minute, ampm] = _ . match (/([0-9]+):([0-9]+)\s*([ap]?)/)
+
+ let new_ampm = ampm == "" ? hour >= 12 ? "pm" : "am" : ""
+
+ hour = hour % 12
+ if (ampm == "" && hour == 0) {
+ hour = 12
+ }
+ if (ampm == "p") {
+ hour += 12
+ }
+
+ printf (process . stdout, "%02d:%02d%s\n", hour, minute, new_ampm)
+});
diff --git a/challenge-100/abigail/node/ch-2.js b/challenge-100/abigail/node/ch-2.js
new file mode 100644
index 0000000000..c7f446d730
--- /dev/null
+++ b/challenge-100/abigail/node/ch-2.js
@@ -0,0 +1,27 @@
+#!/usr/local/bin/node
+
+//
+// See ../README.md
+//
+
+//
+// Run as: node ch-2.js < input-file
+//
+
+let numbers =
+ require ("fs")
+. readFileSync (0) // Read all.
+. toString () // Turn it into a string.
+. split ("\n") // Split on newlines.
+. filter (_ => _ . length) // Filter out empty lines.
+. map (_ => _ . split (/\s+/) // Split on white space.
+ . map (_ => Number (_))) // Convert to number.
+
+for (let x = numbers . length - 2; x >= 0; x --) {
+ for (let y = 0; y < numbers [x] . length; y ++) {
+ numbers [x] [y] += Math . min (numbers [x + 1] [y],
+ numbers [x + 1] [y + 1])
+ }
+}
+
+console . log (numbers [0] [0])
diff --git a/challenge-100/abigail/perl/ch-1.pl b/challenge-100/abigail/perl/ch-1.pl
new file mode 100644
index 0000000000..b50ab54ca8
--- /dev/null
+++ b/challenge-100/abigail/perl/ch-1.pl
@@ -0,0 +1,41 @@
+#!/opt/perl/bin/perl
+
+use 5.032;
+
+use strict;
+use warnings;
+no warnings 'syntax';
+
+use experimental 'signatures';
+use experimental 'lexical_subs';
+
+#
+# See ../README.md
+#
+
+#
+# Run as: perl ch-1.pl < input-file
+#
+
+while (<>) {
+ #
+ # Parse the input, and replace it.
+ # If we have a time ending at PM, add 12 to the hour (unless the
+ # hour is already 12). If we have a time ending with AM, leave
+ # the hour as is, unless it's 12, then it becomes 0. If no AM/PM
+ # is given, subtract 12 from the hour if it's 12 or larger, and
+ # add 12 if it's 0 (after the possible subtraction).
+ #
+ # Minutes always stay what they are.
+ #
+ # Add PM/AM if there was no AM/PM before -- add PM if the hour
+ # is 12 or larger, AM otherwise.
+ #
+ say s {^\s* ([0-9]+) : ([0-9]+) \s* ([pa]?)m? \s*\n}
+ {sprintf "%02d:%02d%s",
+ $3 ? ($1 % 12) + (lc ($3) eq "a" ? 0 : 12)
+ : ($1 % 12) || 12,
+ $2,
+ $3 ? ""
+ : $1 >= 12 ? "pm" : "am"}xeir
+}
diff --git a/challenge-100/abigail/perl/ch-2.pl b/challenge-100/abigail/perl/ch-2.pl
new file mode 100644
index 0000000000..f228dea943
--- /dev/null
+++ b/challenge-100/abigail/perl/ch-2.pl
@@ -0,0 +1,32 @@
+#!/opt/perl/bin/perl
+
+use 5.032;
+
+use strict;
+use warnings;
+no warnings 'syntax';
+
+use experimental 'signatures';
+use experimental 'lexical_subs';
+
+#
+# See ../README.md
+#
+
+#
+# Run as: perl ch-2.pl < input-file
+#
+
+my @nums = map {[/-?[0-9]+/g]} <>;
+
+#
+# Calculate the minimum path bottom to top
+#
+for (my $x = @nums - 2; $x >= 0; $x --) {
+ foreach my $y (keys @{$nums [$x]}) {
+ $nums [$x] [$y] += $nums [$x + 1] [$y] < $nums [$x + 1] [$y + 1]
+ ? $nums [$x + 1] [$y] : $nums [$x + 1] [$y + 1]
+ }
+}
+
+say $nums [0] [0];
diff --git a/challenge-100/abigail/python/ch-1.py b/challenge-100/abigail/python/ch-1.py
new file mode 100644
index 0000000000..c236191663
--- /dev/null
+++ b/challenge-100/abigail/python/ch-1.py
@@ -0,0 +1,50 @@
+#!/opt/local/bin/python
+
+#
+# See ../README.md
+#
+
+#
+# Run as python ch-1.py < input-file
+#
+
+import fileinput
+import re
+
+
+for line in fileinput . input ():
+ #
+ # Parse input
+ #
+ hour, minute, ampm = re . compile (r'([0-9]+):([0-9]+)\s*([ap]?)') \
+ . match (line) \
+ . groups ()
+ #
+ # Make sure we have integers
+ #
+ hour = int (hour)
+ minute = int (minute)
+
+ #
+ # Calculate new AM/PM marker
+ #
+ new_ampm = ""
+ if ampm == "":
+ if hour >= 12:
+ new_ampm = "pm"
+ else:
+ new_ampm = "am"
+
+ #
+ # Calculate new hour
+ #
+ hour = hour % 12
+ if ampm == "" and hour == 0:
+ hour = 12
+ if ampm == "p":
+ hour = hour + 12
+
+ #
+ # Print result
+ #
+ print ("{:02d}:{:02d}{:s}" . format (hour, minute, new_ampm))
diff --git a/challenge-100/abigail/python/ch-2.py b/challenge-100/abigail/python/ch-2.py
new file mode 100644
index 0000000000..b237f83d16
--- /dev/null
+++ b/challenge-100/abigail/python/ch-2.py
@@ -0,0 +1,36 @@
+#!/opt/local/bin/python
+
+#
+# See ../README.md
+#
+
+#
+# Run as python ch-2.py < input-file
+#
+
+import fileinput
+import re
+
+numbers = []
+
+#
+# Read in the data
+#
+for line in fileinput . input ():
+ numbers . append (list (map (lambda x: int (x),
+ re . compile (r'\s+')
+ . split (line . strip ()))))
+
+
+#
+# Calculate the minimum path, bottom to top
+#
+for x in range (len (numbers) - 2, -1, -1):
+ for y in range (0, len (numbers [x])):
+ numbers [x] [y] = numbers [x] [y] + min (numbers [x + 1] [y],
+ numbers [x + 1] [y + 1])
+
+#
+# Print result
+#
+print (numbers [0] [0])
diff --git a/challenge-100/abigail/ruby/ch-1.rb b/challenge-100/abigail/ruby/ch-1.rb
new file mode 100644
index 0000000000..012c2e700f
--- /dev/null
+++ b/challenge-100/abigail/ruby/ch-1.rb
@@ -0,0 +1,43 @@
+#!/usr/bin/ruby
+
+#
+# See ../README.md
+#
+
+#
+# Run as: ruby ch-1.rb < input-file
+#
+
+ARGF . each_line do |_|
+ #
+ # Parse data. Note that we have to map the hours and
+ # minutes from strings to integers.
+ #
+ m = _ . match /(?<hour>[0-9]+):(?<minute>[0-9]+)\s*(?<ampm>[ap]?)/
+ hour = m [:hour] . to_i
+ minute = m [:minute] . to_i