From 05958e021f9a1368c83dbfe0b76c387d481f7fb6 Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 8 Nov 2021 23:43:11 +0100 Subject: Tests for week 138 --- challenge-138/abigail/t/ctest.ini | 8 ++++++++ challenge-138/abigail/t/input-1-1 | 2 ++ challenge-138/abigail/t/input-2-1 | 3 +++ challenge-138/abigail/t/output-1-1.exp | 2 ++ challenge-138/abigail/t/output-2-1.exp | 3 +++ 5 files changed, 18 insertions(+) create mode 100644 challenge-138/abigail/t/ctest.ini create mode 100644 challenge-138/abigail/t/input-1-1 create mode 100644 challenge-138/abigail/t/input-2-1 create mode 100644 challenge-138/abigail/t/output-1-1.exp create mode 100644 challenge-138/abigail/t/output-2-1.exp diff --git a/challenge-138/abigail/t/ctest.ini b/challenge-138/abigail/t/ctest.ini new file mode 100644 index 0000000000..527781acbb --- /dev/null +++ b/challenge-138/abigail/t/ctest.ini @@ -0,0 +1,8 @@ +# +# Configuration file for running tests, using ctest. +# See https://github.com/Abigail/Misc/blob/master/ctest +# + +[names] +1-1 = Given Examples +2-1 = Given Examples diff --git a/challenge-138/abigail/t/input-1-1 b/challenge-138/abigail/t/input-1-1 new file mode 100644 index 0000000000..bedf748f35 --- /dev/null +++ b/challenge-138/abigail/t/input-1-1 @@ -0,0 +1,2 @@ +2021 +2020 diff --git a/challenge-138/abigail/t/input-2-1 b/challenge-138/abigail/t/input-2-1 new file mode 100644 index 0000000000..e388b97ecb --- /dev/null +++ b/challenge-138/abigail/t/input-2-1 @@ -0,0 +1,3 @@ +81 +9801 +36 diff --git a/challenge-138/abigail/t/output-1-1.exp b/challenge-138/abigail/t/output-1-1.exp new file mode 100644 index 0000000000..dc9667c339 --- /dev/null +++ b/challenge-138/abigail/t/output-1-1.exp @@ -0,0 +1,2 @@ +261 +262 diff --git a/challenge-138/abigail/t/output-2-1.exp b/challenge-138/abigail/t/output-2-1.exp new file mode 100644 index 0000000000..2f1465d159 --- /dev/null +++ b/challenge-138/abigail/t/output-2-1.exp @@ -0,0 +1,3 @@ +1 +1 +0 -- cgit From 8ac7ce4cd04ee377060f1d73f5169b680bfba190 Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 8 Nov 2021 23:44:00 +0100 Subject: Perl solution for week 138, part 1 --- challenge-138/abigail/perl/ch-1.pl | 89 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 challenge-138/abigail/perl/ch-1.pl diff --git a/challenge-138/abigail/perl/ch-1.pl b/challenge-138/abigail/perl/ch-1.pl new file mode 100644 index 0000000000..eae1bea355 --- /dev/null +++ b/challenge-138/abigail/perl/ch-1.pl @@ -0,0 +1,89 @@ +#!/opt/perl/bin/perl + +use 5.028; + +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 +# + +# +# A year can have 260, 261 or 262 workdays. +# +# Regular years start and end on the same day of the week. Which means +# that if Jan 1 is a workday, then Dec 31 is, and hence, the year has +# 261 workdays. If Jan 1 is a weekday, the year has 260 workdays. +# +# Leap years ends on a day which is one day later than the day of the +# week it starts on. So, if Jan 1 is Monday to Thursday, the year ends +# on a Tuesday to Friday, resulting in a year with 262 workdays. If the +# year starts on a Friday, it ends on a Saturday, giving 261 workdays. +# If the year starts on a Saturday, it ends on a Sunday, giving 260 workdays, +# and if the year starts on a Sunday, it ends on a Monday, giving 261 +# workdays. +# +# So, we could make a lookup table, based on the day of the week of +# Jan 1, and whether the year is a leap day or not. But we won't. Since +# last weeks challenge made us calculate the Doomsday value of the year, +# we will make a lookup table based on that. The Doomsday value is the +# day of the week on Jan 3 (regular years), or Jan 4 (leap years). +# +# This gives us the following table: +# +# +-------+----------+-------+----------+ +# | Regular Year | Leap Year | +# +----------------+-------+----------+-------+----------+ +# | Doomsday value | Jan 1 | Workdays | Jan 1 | Workdays | +# +----------------+-------+----------+-------+----------+ +# | 0 | Thu | 261 | Wed | 262 | +# | 1 | Fri | 261 | Thu | 262 | +# | 2 | Sat | 260 | Fri | 261 | +# | 3 | Sun | 260 | Sat | 260 | +# | 4 | Mon | 261 | Sun | 261 | +# | 5 | Tue | 261 | Mon | 262 | +# | 6 | Wed | 261 | Tue | 262 | +# +----------------+-------+----------+-------+----------+ + +my @lookup = ( + [261, 261, 260, 260, 261, 261, 261], # Regular years + [262, 262, 261, 260, 261, 262, 262], # Leap years +); + +my $SUNDAY = 0; +my $MONDAY = 1; +my $TUESDAY = 2; +my $WEDNESDAY = 3; +my $THURSDAY = 4; +my $FRIDAY = 5; +my $SATURDAY = 6; + +# +# Given a year, return its "Doomsday" value. +# 0 -> Sunday, 6 -> Saturday +# +sub doomsday ($year) { + use integer; + my $anchor = ($TUESDAY, $SUNDAY, $FRIDAY, $WEDNESDAY) [($year / 100) % 4]; + my $y = $year % 100; + my $doomsday = ((($y / 12) + ($y % 12) + (($y % 12) / 4)) + $anchor) % 7; + $doomsday; +} + +sub is_leap ($year) { + ($year % 400 == 0) || ($year % 4 == 0) && ($year % 100 != 0) ? 1 : 0 +} + + +while (<>) { + say $lookup [is_leap $_] [doomsday $_] +} -- cgit From 04bf8a1351c8d90860e2d5865779d85db3c60f50 Mon Sep 17 00:00:00 2001 From: Abigail Date: Mon, 8 Nov 2021 23:59:46 +0100 Subject: Perl solution for week 138, part 2 --- challenge-138/abigail/perl/ch-2.pl | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 challenge-138/abigail/perl/ch-2.pl diff --git a/challenge-138/abigail/perl/ch-2.pl b/challenge-138/abigail/perl/ch-2.pl new file mode 100644 index 0000000000..b9169688ee --- /dev/null +++ b/challenge-138/abigail/perl/ch-2.pl @@ -0,0 +1,63 @@ +#!/opt/perl/bin/perl + +use 5.028; + +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 solve this with a recursive function. "can_split" gets two arguments, +# '$target', the number we have to achieve as a sum of parts, and +# '$number', the number we have to split into parts. +# +# If $target exceeds $number, we return 0, as we cannot split a number into +# parts and have it sum to something larger. +# If $target equals $number, we return 1, as we can trivial fulfill this. +# +# Else, we take ever larger parts from the end, subtract that part from +# $target, and recurse. If no part succeeds, we have a failure. If any +# part succeeds, we have a winner. +# +# Note that the only two numbers where the sqrt is equal to itself are +# 0 and 1 -- we have to exclude those as we need to split the original +# number into at least two parts. For all other numbers, its square root +# will be less, so not splitting the original number can't sum to the +# square root. +# + +sub can_split ($target, $number) { + return 0 if $target > $number || $target < 0; + return 1 if $target == $number; + + my $pow_10 = 10; + # + # We could use substring instead of modolu and division, but modulo + # and division we can trivially port to other language solutions, + # while taking substrings requires more work. + # + while ($pow_10 < $number) { + use integer; + return 1 if can_split ($target - ($number % $pow_10), + $number / $pow_10); + $pow_10 *= 10; + } + + return 0; +} + +while (<>) { + chomp; + say $_ > 1 && can_split (sqrt ($_), $_) ? 1 : 0 +} -- cgit