From 35ec4c49502579d2a12a9925469e9a890607f3cb Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 8 Mar 2021 14:31:47 +0100 Subject: README for week 103 --- challenge-103/abigail/README.md | 156 +++++++++++++++++++++------------------- 1 file changed, 82 insertions(+), 74 deletions(-) diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index 155dd42f95..c9089c7c0e 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -1,103 +1,111 @@ # 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. +### Solutions -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. +### Blog -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. +## [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. -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. +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. +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): -### Solutions -* [AWK](awk/ch-1.awk) -* [Bash](bash/ch-1.sh) -* [BASIC](basic/ch-1.bas) -* [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) +~~~~ +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)" +~~~~ -### Blog -[Perl Weekly Challenge 102: Rare Numbers](https://wp.me/pcxd30-t7) +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). +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. -## [Hash-counting String](https://perlweeklychallenge.org/blog/perl-weekly-challenge-102/#TASK2) +Optional: Also display the current position in the media as a time-like value. -You are given a positive integer `$N`. +### Example +~~~~ +Input: 3 command line parameters: start time, current time, file name -Write a script to produce Hash-counting string of that length. + # Streamer start time: Tue Nov 24 12:22:03 2020 + 1606134123 -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 + # Current time: Mon Mar 1 09:34:36 2021 + 1614591276 -It can be shown that for every positive integer `N` there is exactly one -such length-`N` string. + # filelist.csv -### Examples -~~~~ -(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 +Output: + + "Les Miserables Episode 1: The Bishop (broadcast date: 1937-07-23)" + 00:17:33 ~~~~ ### Solutions -* [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) -* [Perl](perl/ch-2.pl) -* [Python](python/ch-2.py) -* [Ruby](ruby/ch-2.rb) ### Blog -[Perl Weekly Challenge 102: Hash-counting String](https://wp.me/pcxd30-tZ) -- cgit From 27fb5b5ceb3176f713be38af24329a50d849379d Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 8 Mar 2021 14:38:29 +0100 Subject: Given examples for week 103, part 1 --- challenge-103/abigail/t/ctest.ini | 2 ++ challenge-103/abigail/t/input-1-1 | 2 ++ challenge-103/abigail/t/output-1-1.exp | 2 ++ 3 files changed, 6 insertions(+) create mode 100644 challenge-103/abigail/t/ctest.ini create mode 100644 challenge-103/abigail/t/input-1-1 create mode 100644 challenge-103/abigail/t/output-1-1.exp diff --git a/challenge-103/abigail/t/ctest.ini b/challenge-103/abigail/t/ctest.ini new file mode 100644 index 0000000000..dfdaba67e0 --- /dev/null +++ b/challenge-103/abigail/t/ctest.ini @@ -0,0 +1,2 @@ +[names] +1-1 = Given Examples diff --git a/challenge-103/abigail/t/input-1-1 b/challenge-103/abigail/t/input-1-1 new file mode 100644 index 0000000000..656d00ba31 --- /dev/null +++ b/challenge-103/abigail/t/input-1-1 @@ -0,0 +1,2 @@ +2017 +1938 diff --git a/challenge-103/abigail/t/output-1-1.exp b/challenge-103/abigail/t/output-1-1.exp new file mode 100644 index 0000000000..1eea1683d2 --- /dev/null +++ b/challenge-103/abigail/t/output-1-1.exp @@ -0,0 +1,2 @@ +Yin Fire Rooster +Yang Earth Tiger -- cgit From bac7a4e650e51bbf5561ff81ff70097f9086f7ab Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 8 Mar 2021 16:03:09 +0100 Subject: Additional test for week 103, part 1 --- challenge-103/abigail/t/ctest.ini | 1 + challenge-103/abigail/t/input-1-2 | 60 ++++++++++++++++++++++++++++++++++ challenge-103/abigail/t/output-1-2.exp | 60 ++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+) create mode 100644 challenge-103/abigail/t/input-1-2 create mode 100644 challenge-103/abigail/t/output-1-2.exp diff --git a/challenge-103/abigail/t/ctest.ini b/challenge-103/abigail/t/ctest.ini index dfdaba67e0..52440f87ec 100644 --- a/challenge-103/abigail/t/ctest.ini +++ b/challenge-103/abigail/t/ctest.ini @@ -1,2 +1,3 @@ [names] 1-1 = Given Examples +1-2 = Current Sexagenary cycle diff --git a/challenge-103/abigail/t/input-1-2 b/challenge-103/abigail/t/input-1-2 new file mode 100644 index 0000000000..544eb7d9e4 --- /dev/null +++ b/challenge-103/abigail/t/input-1-2 @@ -0,0 +1,60 @@ +1984 +1985 +1986 +1987 +1988 +1989 +1990 +1991 +1992 +1993 +1994 +1995 +1996 +1997 +1998 +1999 +2000 +2001 +2002 +2003 +2004 +2005 +2006 +2007 +2008 +2009 +2010 +2011 +2012 +2013 +2014 +2015 +2016 +2017 +2018 +2019 +2020 +2021 +2022 +2023 +2024 +2025 +2026 +2027 +2028 +2029 +2030 +2031 +2032 +2033 +2034 +2035 +2036 +2037 +2038 +2039 +2040 +2041 +2042 +2043 diff --git a/challenge-103/abigail/t/output-1-2.exp b/challenge-103/abigail/t/output-1-2.exp new file mode 100644 index 0000000000..361a0b4429 --- /dev/null +++ b/challenge-103/abigail/t/output-1-2.exp @@ -0,0 +1,60 @@ +Yang Wood Rat +Yin Wood Ox +Yang Fire Tiger +Yin Fire Rabbit +Yang Earth Dragon +Yin Earth Snake +Yang Metal Horse +Yin Metal Goat +Yang Water Monkey +Yin Water Rooster +Yang Wood Dog +Yin Wood Pig +Yang Fire Rat +Yin Fire Ox +Yang Earth Tiger +Yin Earth Rabbit +Yang Metal Dragon +Yin Metal Snake +Yang Water Horse +Yin Water Goat +Yang Wood Monkey +Yin Wood Rooster +Yang Fire Dog +Yin Fire Pig +Yang Earth Rat +Yin Earth Ox +Yang Metal Tiger +Yin Metal Rabbit +Yang Water Dragon +Yin Water Snake +Yang Wood Horse +Yin Wood Goat +Yang Fire Monkey +Yin Fire Rooster +Yang Earth Dog +Yin Earth Pig +Yang Metal Rat +Yin Metal Ox +Yang Water Tiger +Yin Water Rabbit +Yang Wood Dragon +Yin Wood Snake +Yang Fire Horse +Yin Fire Goat +Yang Earth Monkey +Yin Earth Rooster +Yang Metal Dog +Yin Metal Pig +Yang Water Rat +Yin Water Ox +Yang Wood Tiger +Yin Wood Rabbit +Yang Fire Dragon +Yin Fire Snake +Yang Earth Horse +Yin Earth Goat +Yang Metal Monkey +Yin Metal Rooster +Yang Water Dog +Yin Water Pig -- cgit From 73981bf58f2136d524c5b2a4ad1015411e61faf5 Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 8 Mar 2021 16:45:20 +0100 Subject: Notes for week 103, part 1 --- challenge-103/abigail/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index c9089c7c0e..0634240b07 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -41,6 +41,13 @@ Input: 1938 Output: Earth Tiger ~~~~ +### 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 ### Blog -- cgit From f9160aab6e21549aa9e99e9197ffcb6a3c82f1e4 Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 8 Mar 2021 17:41:56 +0100 Subject: Perl solution for week 103, part 1 --- challenge-103/abigail/perl/ch-1.pl | 51 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 challenge-103/abigail/perl/ch-1.pl diff --git a/challenge-103/abigail/perl/ch-1.pl b/challenge-103/abigail/perl/ch-1.pl new file mode 100644 index 0000000000..b73716a80c --- /dev/null +++ b/challenge-103/abigail/perl/ch-1.pl @@ -0,0 +1,51 @@ +#!/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 +# +# 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. +# + +my $yin_yang = [qw [Yang Yin]]; +my $heavenly_stems = [map {($_) x 2} qw [Metal Water Wood Fire Earth]]; +my $earthly_branches = [qw [Monkey Rooster Dog Pig Rat Ox + Tiger Rabbit Dragon Snake Horse Goat]]; + + +while (my $year = <>) { + $, = " "; + say map {$$_ [$year % @$_]} $yin_yang, $heavenly_stems, $earthly_branches; +} + + +__END__ -- cgit From f2f25420c71fd379993b2230bf9e8c239bb05297 Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 8 Mar 2021 17:02:41 +0100 Subject: AWK solution for week 103, part 1 --- challenge-103/abigail/README.md | 2 ++ challenge-103/abigail/awk/ch-1.awk | 68 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 challenge-103/abigail/awk/ch-1.awk diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index 0634240b07..5a02f03488 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -49,6 +49,8 @@ We will be reading years from standard input, writing results to standard output. ### Solutions +* [AWK](awk/ch-1.awk) +* [Perl](perl/ch-1.pl) ### Blog 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] +} -- cgit From 292e33319493e09adfee8f35a1b67b07e493e75a Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 8 Mar 2021 17:16:35 +0100 Subject: Bash solution for week 103, part 1 --- challenge-103/abigail/README.md | 1 + challenge-103/abigail/bash/ch-1.sh | 50 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 challenge-103/abigail/bash/ch-1.sh diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index 5a02f03488..ee507a9b99 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -50,6 +50,7 @@ output. ### Solutions * [AWK](awk/ch-1.awk) +* [Bash](bash/ch-1.sh) * [Perl](perl/ch-1.pl) ### Blog 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 -- cgit From 30b59df5174d391d0becb21538fe3c2ea298346c Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 8 Mar 2021 17:40:58 +0100 Subject: C solution for week 103, part 1 --- challenge-103/abigail/README.md | 1 + challenge-103/abigail/c/ch-1.c | 57 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 challenge-103/abigail/c/ch-1.c diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index ee507a9b99..e59555b95d 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -51,6 +51,7 @@ output. ### Solutions * [AWK](awk/ch-1.awk) * [Bash](bash/ch-1.sh) +* [C](c/ch-1.c) * [Perl](perl/ch-1.pl) ### Blog 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 +# include +# include + +/* + * 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); +} -- cgit From 6f3ab8c4168aec362fdd50bf6445680bd62cac49 Mon Sep 17 00:00:00 2001 From: Abigail Date: Tue, 9 Mar 2021 00:16:37 +0100 Subject: Python solution for week 103, part 1 --- challenge-103/abigail/README.md | 2 ++ challenge-103/abigail/python/ch-1.py | 45 ++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 challenge-103/abigail/python/ch-1.py diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index e59555b95d..6c40380e9f 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -52,7 +52,9 @@ output. * [AWK](awk/ch-1.awk) * [Bash](bash/ch-1.sh) * [C](c/ch-1.c) +* [Lua](lua/ch-1.lua) * [Perl](perl/ch-1.pl) +* [Python](python/ch-1.py) ### Blog diff --git a/challenge-103/abigail/python/ch-1.py b/challenge-103/abigail/python/ch-1.py new file mode 100644 index 0000000000..ebe2362239 --- /dev/null +++ b/challenge-103/abigail/python/ch-1.py @@ -0,0 +1,45 @@ +#!/opt/local/bin/python + +# +# See ../README.md +# + +# +# Run as python ch-1.py < 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. +# + +yin_yang = ["Yang", "Yin"] +heavenly_stems = ["Metal", "Metal", "Water", "Water", "Wood", "Wood", + "Fire", "Fire", "Earth", "Earth"] +earthly_branches = ["Monkey", "Rooster", "Dog", "Pig", "Rat", "Ox", + "Tiger", "Rabbit", "Dragon", "Snake", "Horse", "Goat"] + + +import fileinput + +for year in fileinput . input (): + year = int (year) + print (yin_yang [year % len (yin_yang)], + heavenly_stems [year % len (heavenly_stems)], + earthly_branches [year % len (earthly_branches)]) -- cgit From d2bc04d70173727d35ad316ca1fd60d563b36361 Mon Sep 17 00:00:00 2001 From: Abigail Date: Tue, 9 Mar 2021 00:26:24 +0100 Subject: Ruby solution for week 103, part 1 --- challenge-103/abigail/README.md | 1 + challenge-103/abigail/ruby/ch-1.rb | 45 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 challenge-103/abigail/ruby/ch-1.rb diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index 6c40380e9f..59ef92c416 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -55,6 +55,7 @@ output. * [Lua](lua/ch-1.lua) * [Perl](perl/ch-1.pl) * [Python](python/ch-1.py) +* [Ruby](ruby/ch-1.rb) ### Blog diff --git a/challenge-103/abigail/ruby/ch-1.rb b/challenge-103/abigail/ruby/ch-1.rb new file mode 100644 index 0000000000..69b6b21561 --- /dev/null +++ b/challenge-103/abigail/ruby/ch-1.rb @@ -0,0 +1,45 @@ +#!/usr/bin/ruby + +# +# See ../README.md +# + +# +# Run as: ruby ch-1.rb < 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. +# + +yin_yang = ["Yang", "Yin"] +heavenly_stems = ["Metal", "Metal", "Water", "Water", "Wood", "Wood", + "Fire", "Fire", "Earth", "Earth"] +earthly_branches = ["Monkey", "Rooster", "Dog", "Pig", "Rat", "Ox", + "Tiger", "Rabbit", "Dragon", "Snake", "Horse", "Goat"] + + +ARGF . each_line do |year| + year = year . to_i + print yin_yang [year % yin_yang . length] + " " + + heavenly_stems [year % heavenly_stems . length] + " " + + earthly_branches [year % earthly_branches . length] + "\n" +end + -- cgit From a52b542206c6a040bcb6400ad4114603d9291611 Mon Sep 17 00:00:00 2001 From: Abigail Date: Tue, 9 Mar 2021 00:40:50 +0100 Subject: Node.js solution for week 103, part 1 --- challenge-103/abigail/README.md | 1 + challenge-103/abigail/node/ch-1.js | 45 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 challenge-103/abigail/node/ch-1.js diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index 59ef92c416..64e7d3ebf9 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -53,6 +53,7 @@ output. * [Bash](bash/ch-1.sh) * [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) diff --git a/challenge-103/abigail/node/ch-1.js b/challenge-103/abigail/node/ch-1.js new file mode 100644 index 0000000000..d2f18df56c --- /dev/null +++ b/challenge-103/abigail/node/ch-1.js @@ -0,0 +1,45 @@ +#!/usr/local/bin/node + +// +// See ../README.md +// + +// +// Run as: node ch-1.js < 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. +// + +let yin_yang = ["Yang", "Yin"] +let heavenly_stems = ["Metal", "Metal", "Water", "Water", "Wood", "Wood", + "Fire", "Fire", "Earth", "Earth"] +let earthly_branches = ["Monkey", "Rooster", "Dog", "Pig", "Rat", "Ox", + "Tiger", "Rabbit", "Dragon", "Snake", "Horse", "Goat"] + + +require ('readline') . createInterface ({input: process . stdin}) + . on ('line', _ => { + let year = + _ + console . log (yin_yang [year % yin_yang . length], + heavenly_stems [year % heavenly_stems . length], + earthly_branches [year % earthly_branches . length]) +}) -- cgit From 82efe73a6d072b78954e3e44731fad7b6a082111 Mon Sep 17 00:00:00 2001 From: Abigail Date: Tue, 9 Mar 2021 01:22:07 +0100 Subject: Befunge-93 solution for week 103, part 1 --- challenge-103/abigail/README.md | 1 + challenge-103/abigail/befunge-93/ch-1.bf93 | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 challenge-103/abigail/befunge-93/ch-1.bf93 diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index 64e7d3ebf9..d741262679 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -51,6 +51,7 @@ output. ### Solutions * [AWK](awk/ch-1.awk) * [Bash](bash/ch-1.sh) +* [Befunge-93](befunge-93/ch-1.bf93) * [C](c/ch-1.c) * [Lua](lua/ch-1.lua) * [Node.js](node/ch-1.js) 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 -- cgit From d64757d2749e0272e996cebef3fe90bc969d624f Mon Sep 17 00:00:00 2001 From: Abigail Date: Thu, 11 Mar 2021 16:09:18 +0100 Subject: Example for week 103, part 2 --- challenge-103/abigail/t/ctest.ini | 1 + challenge-103/abigail/t/input-2-1 | 1 + challenge-103/abigail/t/media.csv | 7 +++++++ challenge-103/abigail/t/output-2-1.exp | 2 ++ 4 files changed, 11 insertions(+) create mode 100644 challenge-103/abigail/t/input-2-1 create mode 100644 challenge-103/abigail/t/media.csv create mode 100644 challenge-103/abigail/t/output-2-1.exp diff --git a/challenge-103/abigail/t/ctest.ini b/challenge-103/abigail/t/ctest.ini index 52440f87ec..8a8879e52a 100644 --- a/challenge-103/abigail/t/ctest.ini +++ b/challenge-103/abigail/t/ctest.ini @@ -1,3 +1,4 @@ [names] 1-1 = Given Examples 1-2 = Current Sexagenary cycle +2-1 = Given Example diff --git a/challenge-103/abigail/t/input-2-1 b/challenge-103/abigail/t/input-2-1 new file mode 100644 index 0000000000..e9686fda1d --- /dev/null +++ b/challenge-103/abigail/t/input-2-1 @@ -0,0 +1 @@ +1606134123 1614591276 t/media.csv diff --git a/challenge-103/abigail/t/media.csv b/challenge-103/abigail/t/media.csv new file mode 100644 index 0000000000..9428b93004 --- /dev/null +++ b/challenge-103/abigail/t/media.csv @@ -0,0 +1,7 @@ +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)" diff --git a/challenge-103/abigail/t/output-2-1.exp b/challenge-103/abigail/t/output-2-1.exp new file mode 100644 index 0000000000..29b62c18da --- /dev/null +++ b/challenge-103/abigail/t/output-2-1.exp @@ -0,0 +1,2 @@ +"Les Miserables Episode 1: The Bishop (broadcast date: 1937-07-23)" +10:24 -- cgit From 52efe6c989305d458ec6b6424bb477246a5bad7a Mon Sep 17 00:00:00 2001 From: Abigail Date: Thu, 11 Mar 2021 16:06:59 +0100 Subject: Perl solution for week 103, part 2 --- challenge-103/abigail/README.md | 1 + challenge-103/abigail/perl/ch-2.pl | 83 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 challenge-103/abigail/perl/ch-2.pl diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index d741262679..0f05539ef8 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -123,5 +123,6 @@ Output: ~~~~ ### Solutions +* [Perl](perl/ch-2.pl) ### Blog diff --git a/challenge-103/abigail/perl/ch-2.pl b/challenge-103/abigail/perl/ch-2.pl new file mode 100644 index 0000000000..811c715a8b --- /dev/null +++ b/challenge-103/abigail/perl/ch-2.pl @@ -0,0 +1,83 @@ +#!/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 +# + +# +# 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. +# + + +while (<>) { + chomp; + my ($start_time, $current_time, $file_name) = split; + # + # You need a 64 bit integer for this; 32 bits of holds + # a five week vacation in milliseconds, but the author + # of the puzzle lives somewhere were people take 14 week + # holidays... + # + my $time_diff = ($current_time - $start_time) * 1000; + + # + # I guess the "gradual drift of the media" must play a role + # somehow, but I can't figure out how. Ignoring it, does + # gives use the right answer of the single given test case though. + # + + open my $fh, "<", $file_name or die "open '$file_name': $!"; + my @tracks; + my $total_time = 0; # Total time to play the entire set of tracks; + # in milliseconds. + while (<$fh>) { + my ($play_time, $title) = split /\s*,\s*/ => $_, 2; + push @tracks => [$play_time => $title]; + $total_time += $play_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. + # + foreach my $track (@tracks) { + if ($time_diff - $$track [0] < 0) { + use integer; + $time_diff = $time_diff / 1000; # Back to seconds. + my $hours = $time_diff / 3600; + my $minutes = ($time_diff % 3600) / 60; + my $seconds = ($time_diff % 60); + say $$track [1], + sprintf ("%02d:%02d:%02d" => $hours, $minutes, $seconds) =~ + s/^00://r; # Remove leading '00:' for track + # shorter than an hour. + last; + } + $time_diff -= $$track [0]; + } +} -- cgit From 790b1c8fe5584b1c6e5754744d7c7d0922a1fd65 Mon Sep 17 00:00:00 2001 From: Abigail Date: Thu, 11 Mar 2021 19:19:02 +0100 Subject: Lua solution for week 103, part 2 --- challenge-103/abigail/README.md | 1 + challenge-103/abigail/lua/ch-2.lua | 81 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 challenge-103/abigail/lua/ch-2.lua diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index 0f05539ef8..03b5dc3a3c 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -123,6 +123,7 @@ Output: ~~~~ ### Solutions +* [Lua](lua/ch-1.lua) * [Perl](perl/ch-2.pl) ### Blog diff --git a/challenge-103/abigail/lua/ch-2.lua b/challenge-103/abigail/lua/ch-2.lua new file mode 100644 index 0000000000..dc39dc3e8a --- /dev/null +++ b/challenge-103/abigail/lua/ch-2.lua @@ -0,0 +1,81 @@ +#!/opt/local/bin/lua + +-- +-- See ../README.md +-- + +-- +-- Run as: lua ch-2.lua < 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. +-- + +for line in io . lines () do + local _, _, start_time, current_time, file_name = + line : find ("(%d+)%s+(%d+)%s+(%S+)") + + -- + -- Time difference in milliseconds + -- + local time_diff = (current_time - start_time) * 1000 + + local tracks = {} + local total_time = 0 + + -- + -- Read in the media file; store the results in the + -- table tracks. + -- + for track in io . lines (file_name) do + local _, _, play_time, title = track : find ("(%d+),(.*)") + local record = {} + record [0] = play_time + record [1] = title + total_time = total_time + play_time + table . insert (tracks, record) + end + + -- + -- We're not interested in playing full loops. + -- + time_diff = 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 _, track in ipairs (tracks) do + if time_diff - track [0] < 0 + then time_diff = math . floor (time_diff / 1000) + local hours = math . floor (time_diff / 3600) + local minutes = math . floor ((time_diff % 3600) / 60) + local seconds = time_diff % 60 + + -- + -- Format a time string + -- + local time + if hours > 0 + then time = string . + format ("%02d:%02d:%02d", hours, minutes, seconds) + else time = string . + format ( "%02d:%02d", minutes, seconds) + end + print (track [1]) + print (time) + break + else time_diff = time_diff - track [0] + end + end +end + + -- cgit From a2ac29d46cceac9bcf5fa5e9881acd5e4496d7e2 Mon Sep 17 00:00:00 2001 From: Abigail Date: Fri, 12 Mar 2021 19:21:36 +0100 Subject: Lua solution for week 103, part 1 --- challenge-103/abigail/README.md | 2 +- challenge-103/abigail/lua/ch-1.lua | 45 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 challenge-103/abigail/lua/ch-1.lua diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index 03b5dc3a3c..8a14476af8 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -123,7 +123,7 @@ Output: ~~~~ ### Solutions -* [Lua](lua/ch-1.lua) +* [Lua](lua/ch-2.lua) * [Perl](perl/ch-2.pl) ### Blog diff --git a/challenge-103/abigail/lua/ch-1.lua b/challenge-103/abigail/lua/ch-1.lua new file mode 100644 index 0000000000..352158ea06 --- /dev/null +++ b/challenge-103/abigail/lua/ch-1.lua @@ -0,0 +1,45 @@ +#!/opt/local/bin/lua + +-- +-- See ../README.md +-- + +-- +-- Run as: lua ch-1.lua < 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. +-- + +local yin_yang = {"Yang", "Yin"}; +local heavenly_stems = {"Metal", "Metal", "Water", "Water", + "Wood", "Wood", "Fire", "Fire", + "Earth", "Earth"}; +local earthly_branches = {"Monkey", "Rooster", "Dog", "Pig", + "Rat", "Ox", "Tiger", "Rabbit", + "Dragon", "Snake", "Horse", "Goat"}; + +for line in io . lines () do + local year = tonumber (line) + io . write (yin_yang [1 + (year % #yin_yang)], " ", + heavenly_stems [1 + (year % #heavenly_stems)], " ", + earthly_branches [1 + (year % #earthly_branches)], "\n") +end -- cgit From 88733249abc9cc7297417b70be218d35cf2ef064 Mon Sep 17 00:00:00 2001 From: Abigail Date: Fri, 12 Mar 2021 19:49:15 +0100 Subject: Python solution for week 103, part 2 --- challenge-103/abigail/README.md | 1 + challenge-103/abigail/python/ch-2.py | 71 ++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 challenge-103/abigail/python/ch-2.py diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index 8a14476af8..bbf2a50037 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -125,5 +125,6 @@ Output: ### Solutions * [Lua](lua/ch-2.lua) * [Perl](perl/ch-2.pl) +* [Python](python/ch-2.py) ### Blog diff --git a/challenge-103/abigail/python/ch-2.py b/challenge-103/abigail/python/ch-2.py new file mode 100644 index 0000000000..56f708220f --- /dev/null +++ b/challenge-103/abigail/python/ch-2.py @@ -0,0 +1,71 @@ +#!/opt/local/bin/python + +# +# See ../README.md +# + +# +# Run as python ch-2.py < 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. +# + +import fileinput + +for line in fileinput . input (): + start_time, current_time, file_name = line . split () + + # + # You need a 64 bit integer for this; 32 bits of holds + # a five week vacation in milliseconds, but the author + # of the puzzle lives somewhere were people take 14 week + # holidays... + # + time_diff = (int (current_time) - int (start_time)) * 1000 + + # + # Parse the media file; store the track into an array tracks. + # + tracks = [] + total_time = 0 + for track in open (file_name, "r"): + play_time, title = track . strip () . split (",", 2) + play_time = int (play_time) + tracks . append ([play_time, title]) + total_time = total_time + play_time + + # + # We're not interested in playing full loops. + # + time_diff = 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 track in tracks: + if time_diff - track [0] < 0: + time_diff = int (time_diff / 1000) + hours = int (time_diff / 3600) + minutes = int ((time_diff % 3600) / 60) + seconds = time_diff % 60 + + if hours > 0: + format_str = "{0}\n{1:02d}:{2:02d}:{3:02d}" + else: + format_str = "{0}\n{2:02d}:{3:02d}" + + print (format_str . format (track [1], hours, minutes, seconds)) + break + else: + time_diff = time_diff - track [0] + -- cgit From d545f046bf04384f9b4f716a7d7acdb321f16e7d Mon Sep 17 00:00:00 2001 From: Abigail Date: Sun, 14 Mar 2021 13:32:34 +0100 Subject: Ruby solution for week 103, part 2 --- challenge-103/abigail/README.md | 1 + challenge-103/abigail/ruby/ch-2.rb | 67 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 challenge-103/abigail/ruby/ch-2.rb diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index bbf2a50037..d35895761f 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -126,5 +126,6 @@ Output: * [Lua](lua/ch-2.lua) * [Perl](perl/ch-2.pl) * [Python](python/ch-2.py) +* [Ruby](ruby/ch-2.rb) ### Blog diff --git a/challenge-103/abigail/ruby/ch-2.rb b/challenge-103/abigail/ruby/ch-2.rb new file mode 100644 index 0000000000..f4695983a4 --- /dev/null +++ b/challenge-103/abigail/ruby/ch-2.rb @@ -0,0 +1,67 @@ +#!/usr/bin/ruby + +# +# See ../README.md +# + +# +# Run as: ruby ch-2.rb < 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. +# + +ARGF . each_line do |_| + start_time, end_time, file_name = _ . split + + # + # Ruby automatically creates big integers if necessary. + # + time_diff = (end_time . to_i - start_time . to_i) * 1000 + + tracks = [] + total_time = 0 + File . open (file_name) do |f| + f . each_line do |track| + run_time, title = track . split ',', 2 + run_time = run_time . to_i + total_time += run_time + tracks . push [run_time, title] + end + end + + # + # 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. + # + tracks . each do |track| + if time_diff - track [0] < 0 + time_diff = (time_diff / 1000) . to_i + hours = (time_diff / 3600) . to_i + minutes = ((time_diff % 3600) / 60) . to_i + seconds = time_diff % 60 + puts (track [1]) + if hours > 0 + puts "%02d:%02d:%02d" % [hours, minutes, seconds] + else + puts "%02d:%02d" % [ minutes, seconds] + end + break + else + time_diff -= track [0] + end + end +end -- cgit From cc9c06d6417c7a55db2a2740f852c9c056f2a77d Mon Sep 17 00:00:00 2001 From: Abigail Date: Sun, 14 Mar 2021 16:55:22 +0100 Subject: GNU AWK solution for week 103, part 2 --- challenge-103/abigail/README.md | 1 + challenge-103/abigail/awk/ch-2.gawk | 75 +++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 challenge-103/abigail/awk/ch-2.gawk diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index d35895761f..4059ddea7e 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -123,6 +123,7 @@ Output: ~~~~ ### Solutions +* [GNU AWK](awk/ch-2.awk) * [Lua](lua/ch-2.lua) * [Perl](perl/ch-2.pl) * [Python](python/ch-2.py) 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] + } + } +} -- cgit From 5f0e63208b7989972d90eb3c62eabae9577659a1 Mon Sep 17 00:00:00 2001 From: Abigail Date: Sun, 14 Mar 2021 18:35:42 +0100 Subject: C solution for week 103, part 2 --- challenge-103/abigail/README.md | 1 + challenge-103/abigail/c/ch-2.c | 142 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 challenge-103/abigail/c/ch-2.c diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index 4059ddea7e..9d90314025 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -124,6 +124,7 @@ Output: ### Solutions * [GNU AWK](awk/ch-2.awk) +* [C](c/ch-2.c) * [Lua](lua/ch-2.lua) * [Perl](perl/ch-2.pl) * [Python](python/ch-2.py) 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 +# include +# include +# include + +/* + * 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, ¤t_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); +} -- cgit From b4dcb4bf524efdd280f55721a05a4572be32e7c7 Mon Sep 17 00:00:00 2001 From: Abigail Date: Sun, 14 Mar 2021 19:10:50 +0100 Subject: Bash solution for week 103, part 2 --- challenge-103/abigail/README.md | 1 + challenge-103/abigail/bash/ch-2.sh | 62 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 challenge-103/abigail/bash/ch-2.sh diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index 9d90314025..69c67fa04e 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -124,6 +124,7 @@ Output: ### Solutions * [GNU 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) 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 -- cgit From c8806dd8c6106b70a7d40a794116e879fdbc7d35 Mon Sep 17 00:00:00 2001 From: Abigail Date: Sun, 14 Mar 2021 19:52:22 +0100 Subject: Node.js solution for week 103, part 2 --- challenge-103/abigail/README.md | 1 + challenge-103/abigail/node/ch-2.js | 69 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 challenge-103/abigail/node/ch-2.js diff --git a/challenge-103/abigail/README.md b/challenge-103/abigail/README.md index 69c67fa04e..b645561bf2 100644 --- a/challenge-103/abigail/README.md +++ b/challenge-103/abigail/README.md @@ -127,6 +127,7 @@ Output: * [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) diff --git a/challenge-103/abigail/node/ch-2.js b/challenge-103/abigail/node/ch-2.js new file mode 100644 index 0000000000..31ed400038 --- /dev/null +++ b/challenge-103/abigail/node/ch-2.js @@ -0,0 +1,69 @@ +#!/usr/local/bin/node + +// +// See ../README.md +// + +// +// Run as: node ch-2.js < input-file +// + +const fs = require ('fs') +const readline = require ('readline') +const printf = require ('printf') + +readline . createInterface ({input: process . stdin}) + . on ('line', _ => main (... _ . split (" "))) + +function main (start_time, current_time, file_name) { + let time_diff = (current_time - start_time) * 1000; + + // + // Read in the media file, into an array tracks. + // Calculate the total time of playing all the tracks. + // + let tracks = require ("fs") . readFileSync (file_name) + . toString () + . split ("\n") + . filter (_ => _ . length) + . map (_ => _ . split (",", 2)) + . map (_ => [+_ [0], _ [1]]) + let total_time = 0; + tracks . forEach (_ => total_time += _ [0]) + + // + // Don't care about full loops + // + time_diff %= total_time + + // + // Find the right track and print it. + // + done = 0 + tracks . forEach (track => { + if (!done) { + if (time_diff - track [0] < 0) { + console . log (track [1]) + time_diff = Math . floor (time_diff / 1000) + let hours = Math . floor (time_diff / 3600) + let minutes = Math . floor ((time_diff % 3600) / 60) + let seconds = time_diff % 60 + + if (hours > 0) { + console . log ( + printf ("%02d:%02d:%02d", hours, minutes, seconds) + ) + } + else { + console . log ( + printf ( "%02d:%02d", minutes, seconds) + ) + } + done = 1 // There's no 'break' when using forEach + } + else { + time_diff -= track [0] + } + } + }) +} -- cgit From c5063a48971bbbf3284d01ea1ab9759d58e05490 Mon Sep 17 00:00:00 2001 From: Abigail Date: Sun, 14 Mar 2021 20:00:34 +0100 Subject: Don't keep files from previous week --- challenge-103/abigail/data/preprocess | 138 ---------------------------------- 1 file changed, 138 deletions(-) delete mode 100755 challenge-103/abigail/data/preprocess 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 "