aboutsummaryrefslogtreecommitdiff
path: root/challenge-103
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2021-03-15 04:30:23 +0000
committerGitHub <noreply@github.com>2021-03-15 04:30:23 +0000
commitfb3d6dd20bc822014e3d131000d3e62bb70e1b74 (patch)
treefcd95962ccd9d81ba066bbc44d79bdfdc9249d16 /challenge-103
parent4030a803a4e22fdfcbeec7c64b026f95e3ab0f1f (diff)
parent242785b25a69db36dcca668daecf287fab155340 (diff)
downloadperlweeklychallenge-club-fb3d6dd20bc822014e3d131000d3e62bb70e1b74.tar.gz
perlweeklychallenge-club-fb3d6dd20bc822014e3d131000d3e62bb70e1b74.tar.bz2
perlweeklychallenge-club-fb3d6dd20bc822014e3d131000d3e62bb70e1b74.zip
Merge pull request #3719 from Abigail/abigail/week-103
Abigail/week 103
Diffstat (limited to 'challenge-103')
-rw-r--r--challenge-103/abigail/README.md154
-rw-r--r--challenge-103/abigail/awk/ch-1.awk68
-rw-r--r--challenge-103/abigail/awk/ch-2.gawk75
-rw-r--r--challenge-103/abigail/bash/ch-1.sh50
-rw-r--r--challenge-103/abigail/bash/ch-2.sh62
-rw-r--r--challenge-103/abigail/befunge-93/ch-1.bf9316
-rw-r--r--challenge-103/abigail/blog.txt1
-rw-r--r--challenge-103/abigail/blog1.txt1
-rw-r--r--challenge-103/abigail/c/ch-1.c57
-rw-r--r--challenge-103/abigail/c/ch-2.c142
-rwxr-xr-xchallenge-103/abigail/data/preprocess138
-rw-r--r--challenge-103/abigail/lua/ch-1.lua45
-rw-r--r--challenge-103/abigail/lua/ch-2.lua81
-rw-r--r--challenge-103/abigail/node/ch-1.js45
-rw-r--r--challenge-103/abigail/node/ch-2.js69
-rw-r--r--challenge-103/abigail/perl/ch-1.pl51
-rw-r--r--challenge-103/abigail/perl/ch-2.pl83
-rw-r--r--challenge-103/abigail/python/ch-1.py45
-rw-r--r--challenge-103/abigail/python/ch-2.py71
-rw-r--r--challenge-103/abigail/ruby/ch-1.rb45
-rw-r--r--challenge-103/abigail/ruby/ch-2.rb67
-rw-r--r--challenge-103/abigail/t/ctest.ini4
-rw-r--r--challenge-103/abigail/t/input-1-12
-rw-r--r--challenge-103/abigail/t/input-1-260
-rw-r--r--challenge-103/abigail/t/input-2-11
-rw-r--r--challenge-103/abigail/t/media.csv7
-rw-r--r--challenge-103/abigail/t/output-1-1.exp2
-rw-r--r--challenge-103/abigail/t/output-1-2.exp60
-rw-r--r--challenge-103/abigail/t/output-2-1.exp2
29 files changed, 1306 insertions, 198 deletions
diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md
index 155dd42f95..f8b761268c 100644
--- a/challenge-103/abigail/README.md
+++ b/challenge-103/abigail/README.md
@@ -1,57 +1,57 @@
# Solution by Abigail
-## [Rare Numbers](https://perlweeklychallenge.org/blog/perl-weekly-challenge-102/#TASK1)
+## [Chinese Zodiac](https://perlweeklychallenge.org/blog/perl-weekly-challenge-103/#TASK1)
+You are given a year `$year`.
-You are given a positive integer `$N`.
-
-Write a script to generate all Rare numbers of size `$N` if exists.
-Please checkout [the page](http://www.shyamsundergupta.com/rare.htm)
+Write a script to determine the *Chinese Zodiac* for the given year
+$year. Please check out [wikipage](https://en.wikipedia.org/wiki/Chinese_zodiac)
for more information about it.
+The animal cycle:
+* Rat
+* Ox
+* Tiger
+* Rabbit
+* Dragon
+* Snake
+* Horse
+* Goat
+* Monkey
+* Rooster
+* Dog
+* Pig
+
+The element cycle:
+* Wood
+* Fire
+* Earth
+* Metal
+* Water
+
### Examples
+#### Example 1
~~~~
-(a) 2 digits: 65
-(b) 6 digits: 621770
-(c) 9 digits: 281089082
+Input: 2017
+Output: Fire Rooster
~~~~
-### Notes
+#### Example 2
+~~~~
+Input: 1938
+Output: Earth Tiger
+~~~~
-There is no simple efficient algorithm for spitting out rare numbers;
-at least not one which can be easily found online.
-
-The code fragments in the OEIS only give code to check whether a
-number is a rare number, and they don't suggest anything other
-than "try all numbers" if you want to find all of the numbers of a
-certain length.
-
-Shyam writes: [*I have developed a computer program in Fortran to
-calculate Rare numbers. In fact with refinement of the code over
-the years, the program has been made so powerful that all numbers
-up to 10^14 can be just checked for Rare numbers in less than a
-minute on Pentium III PC. In few hours I have been able to check
-up to 10^18.*](https://www.primepuzzles.net/conjectures/conj_023.htm)
-but he does not publish his code.
-
-Richard Guy writes [*Here are three problems that have come to light
-recently, each of which can consume unlimited amounts of computer time,
-perhaps without revealing anything
-significant*.](https://www.jstor.org/stable/2325149?seq=1)
-The rare numbers are one of the three problems.
-
-So, we just include a [list of all know rare numbers,
-up to 10^22](https://oeis.org/A035519/b035519.txt)
-and preprocess them so they're bucketed to length. Then it's just
-a matter of reading the desired length, and printing the appropriate
-entry (or the empty string if no rare numbers of that length exist).
-There are only 124 known rare numbers, so preprocessing is very
-feasible.
+### Notes
+We will actually output a three part string; beside the animal and element
+cycles, we also output the yin/yang cycle.
+We will be reading years from standard input, writing results to standard
+output.
### Solutions
* [AWK](awk/ch-1.awk)
* [Bash](bash/ch-1.sh)
-* [BASIC](basic/ch-1.bas)
+* [Befunge-93](befunge-93/ch-1.bf93)
* [C](c/ch-1.c)
* [Lua](lua/ch-1.lua)
* [Node.js](node/ch-1.js)
@@ -60,38 +60,72 @@ feasible.
* [Ruby](ruby/ch-1.rb)
### Blog
-[Perl Weekly Challenge 102: Rare Numbers](https://wp.me/pcxd30-t7)
+[Perl Weekly Challenge 103: Chinese Zodiac](https://wp.me/pcxd30-uS)
+
+
+## [What's playing?](https://perlweeklychallenge.org/blog/perl-weekly-challenge-103/#TASK2)
+Working from home, you decided that on occasion you wanted some
+background noise while working. You threw together a network streamer
+to continuously loop through the files and launched it in a tmux
+(or screen) session, giving it a directory tree of files to play.
+During the day, you connected an audio player to the stream, listening
+through the workday, closing it when done.
+For weeks you connect to the stream daily, slowly noticing a gradual
+drift of the media. After several weeks, you take vacation. When
+you return, you are pleasantly surprised to find the streamer still
+running. Before connecting, however, if you consider the puzzle of
+determining which track is playing.
-## [Hash-counting String](https://perlweeklychallenge.org/blog/perl-weekly-challenge-102/#TASK2)
+After looking at a few modules to read info regarding the media, a
+quick bit of coding gave you a file list. The file list is in a
+simple CSV format, each line containing two fields: the first the
+number of milliseconds in length, the latter the media's title (this
+example is of several episodes available from the MercuryTheatre.info):
-You are given a positive integer `$N`.
+~~~~
+1709363,"Les Miserables Episode 1: The Bishop (broadcast date: 1937-07-23)"
+1723781,"Les Miserables Episode 2: Javert (broadcast date: 1937-07-30)"
+1723781,"Les Miserables Episode 3: The Trial (broadcast date: 1937-08-06)"
+1678356,"Les Miserables Episode 4: Cosette (broadcast date: 1937-08-13)"
+1646043,"Les Miserables Episode 5: The Grave (broadcast date: 1937-08-20)"
+1714640,"Les Miserables Episode 6: The Barricade (broadcast date: 1937-08-27)"
+1714640,"Les Miserables Episode 7: Conclusion (broadcast date: 1937-09-03)"
+~~~~
-Write a script to produce Hash-counting string of that length.
+For this script, you can assume to be provided the following information:
+* the value of `$^T` (`$BASETIME`) of the streamer script,
+* the value of `time()`, and
+* a CSV file containing the media to play consisting of the length in
+ milliseconds and an identifier for the media (title, filename, or other).
-The definition of a hash-counting string is as follows:
-- the string consists only of digits 0-9 and hashes, `'#'`.
-- there are no two consecutive hashes: `"##"` does not appear in your string
-- the last character is a hash
-- the number immediately preceding each hash (if it exists) is the position
- of that hash in the string, with the position being counted up from 1
+Write a program to output which file is currently playing. For
+purposes of this script, you may assume gapless playback, and format
+the output as you see fit.
-It can be shown that for every positive integer `N` there is exactly one
-such length-`N` string.
+Optional: Also display the current position in the media as a time-like value.
-### Examples
+### Example
~~~~
-(a) "#" is the counting string of length 1
-(b) "2#" is the counting string of length 2
-(c) "#3#" is the string of length 3
-(d) "#3#5#7#10#" is the string of length 10
-(e) "2#4#6#8#11#14#" is the string of length 14
+Input: 3 command line parameters: start time, current time, file name
+
+ # Streamer start time: Tue Nov 24 12:22:03 2020
+ 1606134123
+
+ # Current time: Mon Mar 1 09:34:36 2021
+ 1614591276
+
+ # filelist.csv
+
+Output:
+
+ "Les Miserables Episode 1: The Bishop (broadcast date: 1937-07-23)"
+ 00:17:33
~~~~
### Solutions
-* [AWK](awk/ch-2.awk)
+* [GNU AWK](awk/ch-2.awk)
* [Bash](bash/ch-2.sh)
-* [Befunge-93](befunge-93/ch-2.bf93)
* [C](c/ch-2.c)
* [Lua](lua/ch-2.lua)
* [Node.js](node/ch-2.js)
@@ -100,4 +134,4 @@ such length-`N` string.
* [Ruby](ruby/ch-2.rb)
### Blog
-[Perl Weekly Challenge 102: Hash-counting String](https://wp.me/pcxd30-tZ)
+[Perl Weekly Challenge 103: What's playing?](https://wp.me/pcxd30-v6)
diff --git a/challenge-103/abigail/awk/ch-1.awk b/challenge-103/abigail/awk/ch-1.awk
new file mode 100644
index 0000000000..e829f5ab6a
--- /dev/null
+++ b/challenge-103/abigail/awk/ch-1.awk
@@ -0,0 +1,68 @@
+#!/usr/bin/awk
+
+#
+# See ../README.md
+#
+
+#
+# Run as: awk -f ch-1.awk < input-file
+#
+
+#
+# We're reading years from standard input, one year per line, outputting
+# years from the sexagenary cycle [1]. This is slightly more than what
+# the challenge ask; the challenge asks to output the heavenly stem [2],
+# and the earthly branch [3]. But we also output its Yin/Yang.
+#
+# [1] https://en.wikipedia.org/wiki/Sexagenary_cycle
+# [2] https://en.wikipedia.org/wiki/Heavenly_Stems
+# [3] https://en.wikipedia.org/wiki/Earthly_Branches
+#
+
+#
+# Each of the cycles have been rotated so the first entry corresponds to
+# the year 0 in the Proleptic Gregorian calendar. (We're using the
+# convention of having a year 0, as per ISO 8601).
+# That way, we can just mod the year with the number of entries, without
+# first having to subtract something from the year.
+#
+# The heavenly stems last for 2 years, so we just duplicate the entries.
+#
+
+BEGIN {
+ yin_yang [ 0] = "Yang"
+ yin_yang [ 1] = "Yin"
+ yin_yang_size = 2
+
+ heavenly_stems [ 0] = "Metal"
+ heavenly_stems [ 1] = "Metal"
+ heavenly_stems [ 2] = "Water"
+ heavenly_stems [ 3] = "Water"
+ heavenly_stems [ 4] = "Wood"
+ heavenly_stems [ 5] = "Wood"
+ heavenly_stems [ 6] = "Fire"
+ heavenly_stems [ 7] = "Fire"
+ heavenly_stems [ 8] = "Earth"
+ heavenly_stems [ 9] = "Earth"
+ heavenly_stems_size = 10
+
+ earthly_branches [ 0] = "Monkey"
+ earthly_branches [ 1] = "Rooster"
+ earthly_branches [ 2] = "Dog"
+ earthly_branches [ 3] = "Pig"
+ earthly_branches [ 4] = "Rat"
+ earthly_branches [ 5] = "Ox"
+ earthly_branches [ 6] = "Tiger"
+ earthly_branches [ 7] = "Rabbit"
+ earthly_branches [ 8] = "Dragon"
+ earthly_branches [ 9] = "Snake"
+ earthly_branches [10] = "Horse"
+ earthly_branches [11] = "Goat"
+ earthly_branches_size = 12
+}
+
+{
+ print yin_yang [$1 % yin_yang_size], \
+ heavenly_stems [$1 % heavenly_stems_size], \
+ earthly_branches [$1 % earthly_branches_size]
+}
diff --git a/challenge-103/abigail/awk/ch-2.gawk b/challenge-103/abigail/awk/ch-2.gawk
new file mode 100644
index 0000000000..301730b203
--- /dev/null
+++ b/challenge-103/abigail/awk/ch-2.gawk
@@ -0,0 +1,75 @@
+#!/usr/bin/awk
+
+#
+# See ../README.md
+#
+
+#
+# Run as: gawk -f ch-2.gawk < input-file
+#
+
+#
+# We're reading a start time, the current time, and a file name
+# from STDIN, separated by white space. The file contains the
+# tracks played.
+#
+{
+ start_time = $1
+ current_time = $2
+ file_name = $3
+
+ time_diff = (current_time - start_time) * 1000
+
+ nr_of_tracks = 1
+ total_time = 0
+ while ((getline track < file_name > 0)) {
+ #
+ # AWK doesn't have the ability to limit the number of
+ # fields a string is split into, so we use index() and
+ # substring() instead of split() to get the info.
+ #
+ j = index (track, ",")
+ run_time = substr (track, 1, j - 1)
+ title = substr (track, j + 1)
+ tracks [nr_of_tracks, 0] = run_time
+ tracks [nr_of_tracks, 1] = title
+ nr_of_tracks ++
+
+ total_time += run_time
+ }
+
+ #
+ # We're not interested in playing full loops.
+ #
+ time_diff %= total_time
+
+ #
+ # Find the current track playing. If time_diff is less than the
+ # play time of the track, this is the track currently playing. If
+ # so, print the track name (with quotes, as given in the example --
+ # although they don't belong there, as they're from the CSV encoding;
+ # for that reason, we won't deescape anything else either). Otherwise
+ # (track length is shorter than time_diff), we subtrack the length
+ # of the track from time_diff, and continue checking the next track.
+ #
+ for (i = 1; i <= nr_of_tracks; i ++) {
+ if (time_diff - tracks [i, 0] < 0) {
+ time_diff = int (time_diff / 1000)
+ hours = int (time_diff / 3600)
+ minutes = int ((time_diff % 3600) / 60)
+ seconds = time_diff % 60
+ print tracks [i, 1]
+ if (hours > 0) {
+ printf ("%02d:%02d:%02d\n", hours, minutes, seconds)
+ }
+ else {
+ printf ( "%02d:%02d\n", minutes, seconds)
+ }
+
+ break
+ }
+ else {
+ time_diff -= tracks [i, 0]
+ }
+ }
+}
diff --git a/challenge-103/abigail/bash/ch-1.sh b/challenge-103/abigail/bash/ch-1.sh
new file mode 100644
index 0000000000..1afcdf63d3
--- /dev/null
+++ b/challenge-103/abigail/bash/ch-1.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+#
+# See ../README.md
+#
+
+#
+# Run as: bash ch-1.sh < input-file
+#
+
+#
+# We're reading years from standard input, one year per line, outputting
+# years from the sexagenary cycle [1]. This is slightly more than what
+# the challenge ask; the challenge asks to output the heavenly stem [2],
+# and the earthly branch [3]. But we also output its Yin/Yang.
+#
+# [1] https://en.wikipedia.org/wiki/Sexagenary_cycle
+# [2] https://en.wikipedia.org/wiki/Heavenly_Stems
+# [3] https://en.wikipedia.org/wiki/Earthly_Branches
+#
+
+#
+# Each of the cycles have been rotated so the first entry corresponds to
+# the year 0 in the Proleptic Gregorian calendar. (We're using the
+# convention of having a year 0, as per ISO 8601).
+# That way, we can just mod the year with the number of entries, without
+# first having to subtract something from the year.
+#
+# The heavenly stems last for 2 years, so we just duplicate the entries.
+#
+
+declare -a yin_yang
+declare -a heavenly_stems
+declare -a earthly_branches
+
+yin_yang=(Yang Yin)
+yin_yang_size=2
+heavenly_stems=(Metal Metal Water Water Wood Wood Fire Fire Earth Earth)
+heavenly_stems_size=10
+earthly_branches=(Monkey Rooster Dog Pig Rat Ox
+ Tiger Rabbit Dragon Snake Horse Goat)
+earthly_branches_size=12
+
+
+
+while read year
+do echo ${yin_yang[$((year % yin_yang_size))]} \
+ ${heavenly_stems[$((year % heavenly_stems_size))]} \
+ ${earthly_branches[$((year % earthly_branches_size))]}
+done
diff --git a/challenge-103/abigail/bash/ch-2.sh b/challenge-103/abigail/bash/ch-2.sh
new file mode 100644
index 0000000000..e35d48c034
--- /dev/null
+++ b/challenge-103/abigail/bash/ch-2.sh
@@ -0,0 +1,62 @@
+#!/bin/sh
+
+#
+# See ../README.md
+#
+
+#
+# Run as: bash ch-2.sh < input-file
+#
+
+set -f
+
+#
+# Parse input
+#
+while read start_time current_time file_name
+do time_diff=$(((current_time - start_time) * 1000))
+
+ #
+ # Read the media file, storing run times and titles
+ # into two arrays.
+ #
+ declare -a run_times
+ declare -a titles
+ total_time=0
+
+ nr_of_tracks=0
+ while read track
+ do
+ run_time=${track/,*/}
+ title=${track/[^,]*,/}
+ run_times[$nr_of_tracks]=$run_time
+ titles[$nr_of_tracks]=$title
+ ((nr_of_tracks ++))
+ total_time=$((total_time + run_time))
+ done < $file_name
+
+ #
+ # Don't care about full loops played.
+ #
+ time_diff=$((time_diff % total_time))
+
+ #
+ # Find the right track.
+ #
+ for ((i = 0; i < nr_of_tracks; i ++))
+ do
+ if ((time_diff - run_times[i] < 0))
+ then echo ${titles[$i]}
+ time_diff=$((time_diff / 1000))
+ hours=$(( time_diff / 3600))
+ minutes=$(( (time_diff % 3600) / 60))
+ seconds=$(( time_diff % 60))
+ if ((hours > 0))
+ then printf "%02d:%02d:%02d\n" $hours $minutes $seconds
+ else printf "%02d:%02d\n" $minutes $seconds
+ fi
+ break
+ else time_diff=$((time_diff - run_times[i]))
+ fi
+ done
+done
diff --git a/challenge-103/abigail/befunge-93/ch-1.bf93 b/challenge-103/abigail/befunge-93/ch-1.bf93
new file mode 100644
index 0000000000..665ddfac02
--- /dev/null
+++ b/challenge-103/abigail/befunge-93/ch-1.bf93
@@ -0,0 +1,16 @@
+>&:1+!#@_ 345**% 11p "<"89*11g34*%4+p "<"345**11g55+%4+p "<"59*11g2%4+p v
+^ > "v"89*11g34*%4+p "^"345**11g55+%4+p "v"59*11g2%4+p
+
+ v <
+ v "Yang " v ^ "Metal " < ^v "Monkey" v
+ >, v "Yin " v ^ ^v "Rooster"v
+ ^ ,+55 _^#!:< ^ "Water " < ^v "Dog" v
+ ^ ^v "Pig" v
+ ^ "Wood " < ^v "Rat" v
+ ^ ^v "Ox" v
+ ^ "Fire " < ^v "Tiger" v
+ ^ ^v "Rabbit" v
+ ^ "Earth " < ^v "Dragon" v
+ ^ ^v "Snake" v
+ ^v "Horse" v
+ ^< "Goat" v
diff --git a/challenge-103/abigail/blog.txt b/challenge-103/abigail/blog.txt
new file mode 100644
index 0000000000..a67543d008
--- /dev/null
+++ b/challenge-103/abigail/blog.txt
@@ -0,0 +1 @@
+https://wp.me/pcxd30-uS
diff --git a/challenge-103/abigail/blog1.txt b/challenge-103/abigail/blog1.txt
new file mode 100644
index 0000000000..849470497a
--- /dev/null
+++ b/challenge-103/abigail/blog1.txt
@@ -0,0 +1 @@
+https://wp.me/pcxd30-v6
diff --git a/challenge-103/abigail/c/ch-1.c b/challenge-103/abigail/c/ch-1.c
new file mode 100644
index 0000000000..f4974ced54
--- /dev/null
+++ b/challenge-103/abigail/c/ch-1.c
@@ -0,0 +1,57 @@
+# include <stdlib.h>
+# include <stdio.h>
+# include <string.h>
+
+/*
+ * See ../README.md
+ */
+
+/*
+ * Run as: cc -o ch-1.o ch-1.c; ./ch-1.o < input-file
+ */
+
+/*
+ * We're reading years from standard input, one year per line, outputting
+ * years from the sexagenary cycle [1]. This is slightly more than what
+ * the challenge ask; the challenge asks to output the heavenly stem [2],
+ * and the earthly branch [3]. But we also output its Yin/Yang.
+ *
+ * [1] https://en.wikipedia.org/wiki/Sexagenary_cycle
+ * [2] https://en.wikipedia.org/wiki/Heavenly_Stems
+ * [3] https://en.wikipedia.org/wiki/Earthly_Branches
+ *
+
+ *
+ * Each of the cycles have been rotated so the first entry corresponds to
+ * the year 0 in the Proleptic Gregorian calendar. (We're using the
+ * convention of having a year 0, as per ISO 8601).
+ * That way, we can just mod the year with the number of entries, without
+ * first having to subtract something from the year.
+ *
+ * The heavenly stems last for 2 years, so we just duplicate the entries.
+ */
+
+char * yin_yang [ 2] = {"Yang", "Yin"};
+size_t yin_yang_size = 2;
+char * heavenly_stems [10] = {"Metal", "Metal", "Water", "Water",
+ "Wood", "Wood", "Fire", "Fire",
+ "Earth", "Earth"};
+size_t heavenly_stems_size = 10;
+char * earthly_branches [12] = {"Monkey", "Rooster", "Dog", "Pig",
+ "Rat", "Ox", "Tiger", "Rabbit",
+ "Dragon", "Snake", "Horse", "Goat"};
+size_t earthly_branches_size = 12;
+
+
+
+int main (void) {
+ int year;
+
+ while (scanf ("%d", &year) == 1) {
+ printf ("%s %s %s\n", yin_yang [year % yin_yang_size],
+ heavenly_stems [year % heavenly_stems_size],
+ earthly_branches [year % earthly_branches_size]);
+ }
+
+ return (0);
+}
diff --git a/challenge-103/abigail/c/ch-2.c b/challenge-103/abigail/c/ch-2.c
new file mode 100644
index 0000000000..f776892e0c
--- /dev/null
+++ b/challenge-103/abigail/c/ch-2.c
@@ -0,0 +1,142 @@
+# include <stdlib.h>
+# include <stdio.h>
+# include <string.h>
+# include <unistd.h>
+
+/*
+ * See ../README.md
+ */
+
+/*
+ * Run as: cc -o ch-2.o ch-2.c; ./ch-2.o < input-file
+ */
+
+/*
+ * Return a malloced string of the given size, or die with
+ * an error message if it fails.
+ */
+char * malloc_char (size_t size) {
+ char * string = (char *) malloc (size * sizeof (char));
+ if (string == NULL) {
+ perror (NULL);
+ exit (1);
+ }
+ return (string);
+}
+
+int main (void) {
+ char * line = NULL;
+ size_t len = 0;
+ size_t str_len;
+ struct track {
+ long long run_time;
+ char * title;
+ };
+
+ while ((str_len = getline (&line, &len, stdin)) != -1) {
+ long long start_time;
+ long long current_time;
+ long long time_diff;
+ char * file_name = malloc_char (str_len);
+ size_t index;
+ /*
+ * Parse input
+ */
+ if (sscanf (line, "%lld %lld %s",
+ &start_time, &current_time, file_name) != 3) {
+ fprintf (stderr, "Failed to parse input\n");
+ exit (1);
+ }
+
+ /*
+ * Switch to milliseconds
+ */
+ time_diff = (current_time - start_time) * 1000;
+
+ /*
+ * Open the file, and count the number of lines. Then seek back.
+ */
+ FILE * media_file = fopen (file_name, "r");
+ char ch;
+ size_t number_of_tracks = 0;
+ while ((ch = fgetc (media_file)) != EOF) {
+ if (ch == '\n') {
+ number_of_tracks ++;
+ }
+ }
+
+ if (fseek (media_file, 0, SEEK_SET) == -1) {
+ perror ("Fseek failed");
+ exit (1);
+ }
+
+ /*
+ * Allocate memory for the track info.
+ */
+ struct track * tracks = (struct track *)
+ malloc (number_of_tracks * sizeof (struct track));
+
+ if (tracks == NULL) {
+ perror ("Mallocing tracks failed");
+ exit (1);
+ }
+
+ /*
+ * Read the file, line by line, and store it on tracks.
+ */
+ char * mline = NULL;
+ size_t mlen = 0;
+ size_t slen = 0;
+ size_t i = 0;
+ long long total_time = 0;
+ while ((slen = getline (&mline, &mlen, media_file)) != -1) {
+ long long run_time = atoll (mline);
+ char * title = malloc_char (slen);
+ strncpy (title, mline, slen);
+ while (* title != ',') {
+ title ++;
+ }
+ title ++;
+ struct track this_track = {run_time, title};
+ tracks [i ++] = this_track;
+
+ total_time += run_time;
+ }
+
+ /*
+ * Skip complete loops.
+ */
+ time_diff %= total_time;
+
+ /*
+ * Find the right track.
+ */
+ for (size_t i = 0; i < number_of_tracks; i ++) {
+ struct track this_track = tracks [i];
+ if (time_diff - this_track . run_time < 0) {
+ printf ("%s", this_track . title);
+ /*
+ * C uses integer division, which is quite handy here.
+ */
+ time_diff /= 1000;
+ int hours = time_diff / 3600;
+ int minutes = (time_diff % 3600) / 60;
+ int seconds = time_diff % 60;
+ if (hours > 0) {
+ printf ("%02d:%02d:%02d\n", hours, minutes, seconds);
+ }
+ else {
+ printf ( "%02d:%02d\n", minutes, seconds);
+ }
+ break;
+ }
+ else {
+ time_diff -= this_track . run_time;
+ }
+ }
+
+ }
+ free (line);
+
+ return (0);
+}
diff --git a/challenge-103/abigail/data/preprocess b/challenge-103/abigail/data/preprocess
deleted file mode 100755
index 3e16a0fc07..0000000000
--- a/challenge-103/abigail/data/preprocess
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/opt/perl/bin/perl
-
-use 5.032;
-
-use strict;
-use warnings;
-no warnings 'syntax';
-
-use experimental 'signatures';
-use experimental 'lexical_subs';
-
-open my $fh, "<", "rare_numbers.txt" or die "open rare_numbers.txt: $!";
-
-my @buckets;
-
-while (my $rn = <$fh>) {
- chomp $rn;
- $rn =~ s/^[0-9]+\s+//;
- push @{$buckets [length $rn]} => $rn;
-}
-
-my @bs = sort {$a <=> $b} grep {$buckets [$_]} keys @buckets;
-
-
-open my $awk_h, ">", "rn.awk" or die "open rn.awk: $!";
-open my $bash_h, ">", "rn.sh" or die "open rn.sh: $!";
-open my $basic_h, ">", "rn.bas" or die "open rn.bas: $!";
-open my $c_h, ">", "rn.c" or die "open rn.c: $!";
-open my $lua_h, ">", "rn.lua" or die "open rn.lua: $!";
-open my $node_h, ">", "rn.js" or die "open rn.js: $!";
-open my $perl_h, ">", "rn.pl" or die "open rn.pl: $!";
-open my $python_h, ">", "rn.py" or die "open rn.py: $!";
-open my $ruby_h, ">", "rn.rb" or die "open rn.rb: $!";
-
-my $basic_ln = 1000;
-
-say $awk_h "BEGIN {";
-say $bash_h "declare -a rare_numbers\n";
-say $basic_h "$basic_ln INPUT length\n\n";
-say $c_h "char * rare_numbers [23];\n";
-say $c_h "int main () {";
-say $lua_h "rare_numbers = {}\n";
-say $node_h "let rare_numbers = []\n";
-say $perl_h "my \@rare_numbers;\n";
-say $python_h "rare_numbers = {}\n";
-say $ruby_h "rare_numbers = Array . new";
-
-foreach my $bs (0 .. 22) {
- if (!$buckets [$bs]) {
- printf $c_h " rare_numbers [%2d] = NULL;\n"
- => $bs;
- next;
- }
-
- #
- # AWK
- #
- printf $awk_h ' rare_numbers [%2d] = ', $bs;
- print $awk_h join " \\\n " =>
- map {sprintf "%26s", qq {"$_\\n"}} @{$buckets [$bs]};
- print $awk_h "\n";
-
- #
- # Bash
- #
- printf $bash_h 'rare_numbers[%2d]=', $bs;
- print $bash_h join "\\\n" =>
- map {qq {"$_\\n"}} @{$buckets [$bs]};
- print $bash_h "\n";
-
- #
- # BASIC
- #
- for my $rn (@{$buckets [$bs]}) {
- printf $basic_h qq {%03d IF length = %2d THEN PRINT %24s\n}
- => ($basic_ln += 10), $bs, qq {"$rn"}
- }
-
- #
- # C
- #
- printf $c_h '