From 186c7a1cc1725604e38d55917587f9ea9536fac3 Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 15 Feb 2021 17:56:46 +0100 Subject: README file for week 100. --- challenge-100/abigail/README.md | 125 +++++++++++++++------------------------- 1 file changed, 46 insertions(+), 79 deletions(-) diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md index 56e481bb08..c5d4ca73db 100644 --- a/challenge-100/abigail/README.md +++ b/challenge-100/abigail/README.md @@ -1,110 +1,77 @@ # 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) -* [Bash](bash/ch-1.sh) -* [C](c/ch-1.ch) -* [Perl](perl/ch-1.pl) ### 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 -* [Bash](bash/ch-2.sh) -* [Perl](perl/ch-2.pl) ### Blog -- cgit From ddc5ddd2467cc05fd885fc582111e800297501d9 Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 15 Feb 2021 17:26:12 +0100 Subject: Examples --- challenge-100/abigail/t/ctest.ini | 11 +++++++++++ challenge-100/abigail/t/input-1-1 | 2 ++ challenge-100/abigail/t/input-1-2 | 24 ++++++++++++++++++++++++ challenge-100/abigail/t/input-1-3 | 24 ++++++++++++++++++++++++ challenge-100/abigail/t/input-2-1 | 4 ++++ challenge-100/abigail/t/input-2-2 | 4 ++++ challenge-100/abigail/t/output-1-1.exp | 2 ++ challenge-100/abigail/t/output-1-2.exp | 24 ++++++++++++++++++++++++ challenge-100/abigail/t/output-1-3.exp | 24 ++++++++++++++++++++++++ challenge-100/abigail/t/output-2-1.exp | 1 + challenge-100/abigail/t/output-2-2.exp | 1 + 11 files changed, 121 insertions(+) create mode 100644 challenge-100/abigail/t/ctest.ini create mode 100644 challenge-100/abigail/t/input-1-1 create mode 100644 challenge-100/abigail/t/input-1-2 create mode 100644 challenge-100/abigail/t/input-1-3 create mode 100644 challenge-100/abigail/t/input-2-1 create mode 100644 challenge-100/abigail/t/input-2-2 create mode 100644 challenge-100/abigail/t/output-1-1.exp create mode 100644 challenge-100/abigail/t/output-1-2.exp create mode 100644 challenge-100/abigail/t/output-1-3.exp create mode 100644 challenge-100/abigail/t/output-2-1.exp create mode 100644 challenge-100/abigail/t/output-2-2.exp diff --git a/challenge-100/abigail/t/ctest.ini b/challenge-100/abigail/t/ctest.ini new file mode 100644 index 0000000000..cc782701a0 --- /dev/null +++ b/challenge-100/abigail/t/ctest.ini @@ -0,0 +1,11 @@ +# +# Configuration file for running tests, using ctest. +# See https://github.com/Abigail/Misc/blob/master/ctest +# + +[names] +1-1 = Given examples +1-2 = All hours 24 -> 12 +1-3 = All hours 12 -> 24 +2-1 = Given example 1 +2-2 = Given example 2 diff --git a/challenge-100/abigail/t/input-1-1 b/challenge-100/abigail/t/input-1-1 new file mode 100644 index 0000000000..3631b1d2bc --- /dev/null +++ b/challenge-100/abigail/t/input-1-1 @@ -0,0 +1,2 @@ +05:15pm +19:15 diff --git a/challenge-100/abigail/t/input-1-2 b/challenge-100/abigail/t/input-1-2 new file mode 100644 index 0000000000..476b4e6afe --- /dev/null +++ b/challenge-100/abigail/t/input-1-2 @@ -0,0 +1,24 @@ +0:21 +1:21 +2:21 +3:21 +4:21 +5:21 +6:21 +7:21 +8:21 +9:21 +10:21 +11:21 +12:21 +13:21 +14:21 +15:21 +16:21 +17:21 +18:21 +19:21 +20:21 +21:21 +22:21 +23:21 diff --git a/challenge-100/abigail/t/input-1-3 b/challenge-100/abigail/t/input-1-3 new file mode 100644 index 0000000000..83b5e971ee --- /dev/null +++ b/challenge-100/abigail/t/input-1-3 @@ -0,0 +1,24 @@ +12:21am +01:21am +02:21am +03:21am +04:21am +05:21am +06:21am +07:21am +08:21am +09:21am +10:21am +11:21am +12:21pm +01:21pm +02:21pm +03:21pm +04:21pm +05:21pm +06:21pm +07:21pm +08:21pm +09:21pm +10:21pm +11:21pm diff --git a/challenge-100/abigail/t/input-2-1 b/challenge-100/abigail/t/input-2-1 new file mode 100644 index 0000000000..d83aefd667 --- /dev/null +++ b/challenge-100/abigail/t/input-2-1 @@ -0,0 +1,4 @@ +1 +2 4 +6 4 9 +5 1 7 2 diff --git a/challenge-100/abigail/t/input-2-2 b/challenge-100/abigail/t/input-2-2 new file mode 100644 index 0000000000..44e814a1bd --- /dev/null +++ b/challenge-100/abigail/t/input-2-2 @@ -0,0 +1,4 @@ +3 +3 1 +5 2 3 +4 3 1 3 diff --git a/challenge-100/abigail/t/output-1-1.exp b/challenge-100/abigail/t/output-1-1.exp new file mode 100644 index 0000000000..814a185a2f --- /dev/null +++ b/challenge-100/abigail/t/output-1-1.exp @@ -0,0 +1,2 @@ +17:15 +07:15pm diff --git a/challenge-100/abigail/t/output-1-2.exp b/challenge-100/abigail/t/output-1-2.exp new file mode 100644 index 0000000000..83b5e971ee --- /dev/null +++ b/challenge-100/abigail/t/output-1-2.exp @@ -0,0 +1,24 @@ +12:21am +01:21am +02:21am +03:21am +04:21am +05:21am +06:21am +07:21am +08:21am +09:21am +10:21am +11:21am +12:21pm +01:21pm +02:21pm +03:21pm +04:21pm +05:21pm +06:21pm +07:21pm +08:21pm +09:21pm +10:21pm +11:21pm diff --git a/challenge-100/abigail/t/output-1-3.exp b/challenge-100/abigail/t/output-1-3.exp new file mode 100644 index 0000000000..c9353b4892 --- /dev/null +++ b/challenge-100/abigail/t/output-1-3.exp @@ -0,0 +1,24 @@ +00:21 +01:21 +02:21 +03:21 +04:21 +05:21 +06:21 +07:21 +08:21 +09:21 +10:21 +11:21 +12:21 +13:21 +14:21 +15:21 +16:21 +17:21 +18:21 +19:21 +20:21 +21:21 +22:21 +23:21 diff --git a/challenge-100/abigail/t/output-2-1.exp b/challenge-100/abigail/t/output-2-1.exp new file mode 100644 index 0000000000..45a4fb75db --- /dev/null +++ b/challenge-100/abigail/t/output-2-1.exp @@ -0,0 +1 @@ +8 diff --git a/challenge-100/abigail/t/output-2-2.exp b/challenge-100/abigail/t/output-2-2.exp new file mode 100644 index 0000000000..7f8f011eb7 --- /dev/null +++ b/challenge-100/abigail/t/output-2-2.exp @@ -0,0 +1 @@ +7 -- cgit From e70a454f19e816884005be3e9dd78cf592523ae2 Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 15 Feb 2021 18:12:44 +0100 Subject: Perl solution for week 100, part 1 --- challenge-100/abigail/README.md | 1 + challenge-100/abigail/perl/ch-1.pl | 41 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 challenge-100/abigail/perl/ch-1.pl diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md index c5d4ca73db..6199dd6ad1 100644 --- a/challenge-100/abigail/README.md +++ b/challenge-100/abigail/README.md @@ -18,6 +18,7 @@ Output: 07:15 pm or 07:15pm ~~~~ ### Solutions +* [Perl](perl/ch-1.pl) ### Blog 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 +} -- cgit From 7cd38883e76c70fd2828874df890d2db1d3b8e46 Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 15 Feb 2021 18:57:04 +0100 Subject: Perl solution for week 100, part 2 --- challenge-100/abigail/README.md | 1 + challenge-100/abigail/perl/ch-2.pl | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 challenge-100/abigail/perl/ch-2.pl diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md index 6199dd6ad1..f02758c5eb 100644 --- a/challenge-100/abigail/README.md +++ b/challenge-100/abigail/README.md @@ -74,5 +74,6 @@ The minimum path sum from top to bottom: 3 + 1 + 2 + 1 = 7 ~~~~ ### Solutions +* [Perl](perl/ch-2.pl) ### Blog diff --git a/challenge-100/abigail/perl/ch-2.pl b/challenge-100/abigail/perl/ch-2.pl new file mode 100644 index 0000000000..3db6e7d481 --- /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]; -- cgit From cfe5c17546630cdc11f2855b9af585be851a63cb Mon Sep 17 00:00:00 2001 From: Abigail Date: Tue, 16 Feb 2021 20:44:06 +0100 Subject: Befunge-93 solution for week 100, part 1 --- challenge-100/abigail/README.md | 3 +++ challenge-100/abigail/befunge-93/ch-1.bf93 | 15 +++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 challenge-100/abigail/befunge-93/ch-1.bf93 diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md index f02758c5eb..c30e332085 100644 --- a/challenge-100/abigail/README.md +++ b/challenge-100/abigail/README.md @@ -18,6 +18,8 @@ Output: 07:15 pm or 07:15pm ~~~~ ### Solutions +* [GNU AWK](awk/ch-1.gawk) +* [Befunge-93](befunge-93/ch-1.bf93) * [Perl](perl/ch-1.pl) ### Blog @@ -74,6 +76,7 @@ The minimum path sum from top to bottom: 3 + 1 + 2 + 1 = 7 ~~~~ ### Solutions +* [AWK](awk/ch-2.awk) * [Perl](perl/ch-2.pl) ### Blog 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.^ >: ^ -- cgit From 2be3bc463bdbc29c0955db0651bd99038d418794 Mon Sep 17 00:00:00 2001 From: Abigail Date: Tue, 16 Feb 2021 20:47:54 +0100 Subject: GNU AWK solution for week 100, part 1 --- challenge-100/abigail/awk/ch-1.gawk | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 challenge-100/abigail/awk/ch-1.gawk 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" +} -- cgit From 68363c1fc00e26d7d7269d40c7c5281a8f83e076 Mon Sep 17 00:00:00 2001 From: Abigail Date: Tue, 16 Feb 2021 20:48:25 +0100 Subject: AWK solution for week 100, part 2 --- challenge-100/abigail/awk/ch-2.awk | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 challenge-100/abigail/awk/ch-2.awk 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] +} -- cgit From 2170d75727dc2c23772b0348c7576cbcf2a9794c Mon Sep 17 00:00:00 2001 From: Abigail Date: Wed, 17 Feb 2021 01:06:20 +0100 Subject: Bash solution for week 100, part 1 --- challenge-100/abigail/README.md | 1 + challenge-100/abigail/bash/ch-1.sh | 56 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 challenge-100/abigail/bash/ch-1.sh diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md index c30e332085..ffe1862b06 100644 --- a/challenge-100/abigail/README.md +++ b/challenge-100/abigail/README.md @@ -19,6 +19,7 @@ Output: 07:15 pm or 07:15pm ### Solutions * [GNU AWK](awk/ch-1.gawk) +* [Bash](bash/ch-1.sh) * [Befunge-93](befunge-93/ch-1.bf93) * [Perl](perl/ch-1.pl) 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 -- cgit From 55f9274d96dd43136acc8cfdd6e8991fc562fada Mon Sep 17 00:00:00 2001 From: Abigail Date: Wed, 17 Feb 2021 14:21:33 +0100 Subject: Bash solution for week 100, part 2 --- challenge-100/abigail/README.md | 1 + challenge-100/abigail/bash/ch-2.sh | 63 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 challenge-100/abigail/bash/ch-2.sh diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md index ffe1862b06..ddce3fd34a 100644 --- a/challenge-100/abigail/README.md +++ b/challenge-100/abigail/README.md @@ -78,6 +78,7 @@ The minimum path sum from top to bottom: 3 + 1 + 2 + 1 = 7 ### Solutions * [AWK](awk/ch-2.awk) +* [Bash](bash/ch-2.sh) * [Perl](perl/ch-2.pl) ### Blog 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]} -- cgit From ade625b24f12025b278ef2cfaaf857ac81df4319 Mon Sep 17 00:00:00 2001 From: Abigail Date: Wed, 17 Feb 2021 18:43:33 +0100 Subject: C solution for week 100, part 1 --- challenge-100/abigail/README.md | 1 + challenge-100/abigail/c/ch-1.c | 75 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 challenge-100/abigail/c/ch-1.c diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md index ddce3fd34a..ff62f9e3ba 100644 --- a/challenge-100/abigail/README.md +++ b/challenge-100/abigail/README.md @@ -21,6 +21,7 @@ Output: 07:15 pm or 07:15pm * [GNU AWK](awk/ch-1.gawk) * [Bash](bash/ch-1.sh) * [Befunge-93](befunge-93/ch-1.bf93) +* [C](c/ch-1.c) * [Perl](perl/ch-1.pl) ### Blog 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 +# include +# include +# include + +/* + * 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); +} -- cgit From 46a34ac4699c3981c6325652ff34a9087635d70e Mon Sep 17 00:00:00 2001 From: Abigail Date: Wed, 17 Feb 2021 19:43:36 +0100 Subject: C solution for week 100, part 2 --- challenge-100/abigail/README.md | 1 + challenge-100/abigail/c/ch-2.c | 53 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 challenge-100/abigail/c/ch-2.c diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md index ff62f9e3ba..d4f0bcee6b 100644 --- a/challenge-100/abigail/README.md +++ b/challenge-100/abigail/README.md @@ -80,6 +80,7 @@ The minimum path sum from top to bottom: 3 + 1 + 2 + 1 = 7 ### Solutions * [AWK](awk/ch-2.awk) * [Bash](bash/ch-2.sh) +* [C](c/ch-2.c) * [Perl](perl/ch-2.pl) ### Blog 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 +# include +# include +# include + +/* + * 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]); +} -- cgit From 5d34a6625bbb1fb1b92181dddec2459480157f53 Mon Sep 17 00:00:00 2001 From: Abigail Date: Thu, 18 Feb 2021 01:06:54 +0100 Subject: Lua solution for week 100, part 1 --- challenge-100/abigail/README.md | 1 + challenge-100/abigail/lua/ch-1.lua | 56 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 challenge-100/abigail/lua/ch-1.lua diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md index d4f0bcee6b..c3d1134d80 100644 --- a/challenge-100/abigail/README.md +++ b/challenge-100/abigail/README.md @@ -22,6 +22,7 @@ Output: 07:15 pm or 07:15pm * [Bash](bash/ch-1.sh) * [Befunge-93](befunge-93/ch-1.bf93) * [C](c/ch-1.c) +* [Lua](lua/ch-1.lua) * [Perl](perl/ch-1.pl) ### Blog 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 -- cgit From 01816f96772a0ab1db52c09636e686cf47bb95dd Mon Sep 17 00:00:00 2001 From: Abigail Date: Thu, 18 Feb 2021 01:16:29 +0100 Subject: Allow negative numbers. --- challenge-100/abigail/perl/ch-2.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/challenge-100/abigail/perl/ch-2.pl b/challenge-100/abigail/perl/ch-2.pl index 3db6e7d481..f228dea943 100644 --- a/challenge-100/abigail/perl/ch-2.pl +++ b/challenge-100/abigail/perl/ch-2.pl @@ -17,7 +17,7 @@ use experimental 'lexical_subs'; # Run as: perl ch-2.pl < input-file # -my @nums = map {[/[0-9]+/g]} <>; +my @nums = map {[/-?[0-9]+/g]} <>; # # Calculate the minimum path bottom to top -- cgit From 3de02145ce6ede5f1f97fa009d39c72f36b77f1d Mon Sep 17 00:00:00 2001 From: Abigail Date: Thu, 18 Feb 2021 15:39:47 +0100 Subject: Lua solution for week 100, part 2 --- challenge-100/abigail/README.md | 1 + challenge-100/abigail/lua/ch-2.lua | 41 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 challenge-100/abigail/lua/ch-2.lua diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md index c3d1134d80..7e4cf910e0 100644 --- a/challenge-100/abigail/README.md +++ b/challenge-100/abigail/README.md @@ -82,6 +82,7 @@ The minimum path sum from top to bottom: 3 + 1 + 2 + 1 = 7 * [AWK](awk/ch-2.awk) * [Bash](bash/ch-2.sh) * [C](c/ch-2.c) +* [Lua](lua/ch-2.lua) * [Perl](perl/ch-2.pl) ### Blog 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]) -- cgit From b97eda202060a1a635f43117fd185c3642971ba3 Mon Sep 17 00:00:00 2001 From: Abigail Date: Thu, 18 Feb 2021 17:25:10 +0100 Subject: Node.js solution for week 100, part 1 --- challenge-100/abigail/README.md | 1 + challenge-100/abigail/node/ch-1.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 challenge-100/abigail/node/ch-1.js diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md index 7e4cf910e0..80fce6a337 100644 --- a/challenge-100/abigail/README.md +++ b/challenge-100/abigail/README.md @@ -23,6 +23,7 @@ Output: 07:15 pm or 07:15pm * [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) ### Blog 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) +}); -- cgit From 986d1fe0c2e8e37dbbda7fa50ef1e797d58b0df3 Mon Sep 17 00:00:00 2001 From: Abigail Date: Thu, 18 Feb 2021 17:53:29 +0100 Subject: Node.js solution for week 100, part 2 --- challenge-100/abigail/README.md | 1 + challenge-100/abigail/node/ch-2.js | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 challenge-100/abigail/node/ch-2.js diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md index 80fce6a337..ebb35ceda6 100644 --- a/challenge-100/abigail/README.md +++ b/challenge-100/abigail/README.md @@ -84,6 +84,7 @@ The minimum path sum from top to bottom: 3 + 1 + 2 + 1 = 7 * [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) ### Blog 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]) -- cgit From fb62180005f55612297b8a97d061ace97e2d2dc7 Mon Sep 17 00:00:00 2001 From: Abigail Date: Thu, 18 Feb 2021 18:37:20 +0100 Subject: Python solution for week 100, part 1 --- challenge-100/abigail/README.md | 1 + challenge-100/abigail/python/ch-1.py | 50 ++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 challenge-100/abigail/python/ch-1.py diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md index ebb35ceda6..3712290a28 100644 --- a/challenge-100/abigail/README.md +++ b/challenge-100/abigail/README.md @@ -25,6 +25,7 @@ Output: 07:15 pm or 07:15pm * [Lua](lua/ch-1.lua) * [Node.js](node/ch-1.js) * [Perl](perl/ch-1.pl) +* [Python](python/ch-1.py) ### Blog 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)) -- cgit From 66a910dbb2a803dc8e785b6564d4f52eb4e4f560 Mon Sep 17 00:00:00 2001 From: Abigail Date: Fri, 19 Feb 2021 01:16:20 +0100 Subject: Python solution for week 100, part 2 --- challenge-100/abigail/README.md | 1 + challenge-100/abigail/python/ch-2.py | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 challenge-100/abigail/python/ch-2.py diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md index 3712290a28..7afd7bb3f2 100644 --- a/challenge-100/abigail/README.md +++ b/challenge-100/abigail/README.md @@ -87,5 +87,6 @@ The minimum path sum from top to bottom: 3 + 1 + 2 + 1 = 7 * [Lua](lua/ch-2.lua) * [Node.js](node/ch-2.js) * [Perl](perl/ch-2.pl) +* [Python](python/ch-1.py) ### Blog 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]) -- cgit From 5ab72f71a1b4686f5acf6ae5562f2829b0ee9c6e Mon Sep 17 00:00:00 2001 From: Abigail Date: Fri, 19 Feb 2021 01:47:09 +0100 Subject: Ruby solution for week 100, part 1 --- challenge-100/abigail/README.md | 1 + challenge-100/abigail/ruby/ch-1.rb | 43 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 challenge-100/abigail/ruby/ch-1.rb diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md index 7afd7bb3f2..e87dfae955 100644 --- a/challenge-100/abigail/README.md +++ b/challenge-100/abigail/README.md @@ -26,6 +26,7 @@ Output: 07:15 pm or 07:15pm * [Node.js](node/ch-1.js) * [Perl](perl/ch-1.pl) * [Python](python/ch-1.py) +* [Ruby](ruby/ch-1.rb) ### Blog 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 /(?[0-9]+):(?[0-9]+)\s*(?[ap]?)/ + hour = m [:hour] . to_i + minute = m [:minute] . to_i + ampm = m [:ampm] + + # + # Calculate the new AM/PM marker + # + new_ampm = ampm == "" ? hour >= 12 ? "pm" : "am" : "" + + # + # Calculate the new hour + # + hour %= 12 + + if ampm == "" && hour == 0 + then hour = 12 + end + + if ampm == "p" + then hour += 12 + end + + # + # Print the result + # + puts sprintf("%02d:%02d%s", hour, minute, new_ampm) +end -- cgit From c91195bb834b740c54cbd0073961f443bacf4f0e Mon Sep 17 00:00:00 2001 From: Abigail Date: Fri, 19 Feb 2021 02:12:08 +0100 Subject: Ruby solution for week 100, part 2 --- challenge-100/abigail/README.md | 3 ++- challenge-100/abigail/ruby/ch-2.rb | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 challenge-100/abigail/ruby/ch-2.rb diff --git a/challenge-100/abigail/README.md b/challenge-100/abigail/README.md index e87dfae955..e55419aae3 100644 --- a/challenge-100/abigail/README.md +++ b/challenge-100/abigail/README.md @@ -88,6 +88,7 @@ The minimum path sum from top to bottom: 3 + 1 + 2 + 1 = 7 * [Lua](lua/ch-2.lua) * [Node.js](node/ch-2.js) * [Perl](perl/ch-2.pl) -* [Python](python/ch-1.py) +* [Python](python/ch-2.py) +* [Ruby](ruby/ch-2.rb) ### Blog diff --git a/challenge-100/abigail/ruby/ch-2.rb b/challenge-100/abigail/ruby/ch-2.rb new file mode 100644 index 0000000000..1e0396dcef --- /dev/null +++ b/challenge-100/abigail/ruby/ch-2.rb @@ -0,0 +1,35 @@ +#!/usr/bin/ruby + +# +# See ../README.md +# + +# +# Run as: ruby ch-2.rb < input-file +# + +numbers = [] + +# +# Parse the data: iterate over the lines of input, split each +# line on whitespace, turn each item into an integer, and +# add the split elements as a row of numbers to the array numbers. +# +ARGF . each_line do |_| + numbers << _ . split . map {|_| _ . to_i} +end + +# +# Calculate the minimum path, bottom to top +# +(numbers . length - 2) . downto (0) do |x| + (0) . upto (numbers [x] . length - 1) do |y| + numbers [x] [y] += [numbers [x + 1] [y], + numbers [x + 1] [y + 1]] . min + end +end + +# +# Print result +# +puts numbers [0] [0] -- cgit