| 06 November 2026 | Challenge 137 |
Long Loops
TASK #1 › Long Year
Submitted by: Mohammad S Anwar
Write a script to find all the years between 1900 and 2100 which is a Long Year.
A year is Long if it has 53 weeks.
[UPDATED][2021-11-01 16:20:00]: For more information about Long Year, please refer to
wikipedia.
Expected Output
1903, 1908, 1914, 1920, 1925,
1931, 1936, 1942, 1948, 1953,
1959, 1964, 1970, 1976, 1981,
1987, 1992, 1998, 2004, 2009,
2015, 2020, 2026, 2032, 2037,
2043, 2048, 2054, 2060, 2065,
2071, 2076, 2082, 2088, 2093,
2099
Solution
Here is my solution dated 1 Nov 2021:
#!/usr/bin/perl -s
use v5.16;
use warnings;
use DateTime;
# Maybe I'm missing something: The year's last day's week number is the
# year's week count.
say join ' ', grep DateTime->new(year => $_, month => 12, day => 31,
time_zone => 'floating')->week_number == 53, 1900 .. 2100;
TASK #2 › Lychrel Number
Submitted by: Mohammad S Anwar
You are given a number, 10 <= $n <= 1000.
Write a script to find out if the given number is Lychrel number. To keep the task simple, we impose the following rules:
a. Stop if the number of iterations reached 500.
b. Stop if you end up with number >= 10_000_000.
[UPDATED][2021-11-01 16:20:00]: If you stop because of any of the above two rules then we expect 1 as an output.
According to wikipedia:
A Lychrel number is a natural number that cannot form a palindrome through the iterative process of repeatedly reversing its digits and adding the resulting numbers.
Example 1
Input: $n = 56
Output: 0
After 1 iteration, we found palindrome number.
56 + 65 = 121
Example 2
Input: $n = 57
Output: 0
After 2 iterations, we found palindrome number.
57 + 75 = 132
132 + 231 = 363
Example 3
Input: $n = 59
Output: 0
After 3 iterations, we found palindrome number.
59 + 95 = 154
154 + 451 = 605
605 + 506 = 1111
Solution
The given limit for the number of iterations is superfluous. 30 iterations on any number result in a number far beyond 1e7.
Two further test cases:
89is not a Lychrel number, but it exceeds the limit of1e7.196is a candidate for a Lychrel number.
Perl
use strict;
use warnings;
use experimental 'signatures';
use Math::Prime::Util qw(fromdigits todigits);
sub lychrel ($n) {
while () {
my $rev = fromdigits [reverse todigits $n, 10], 10;
return 0 if $n == $rev;
return 1 if $n > 1e7;
$n += $rev;
}
}
See the full solution to task 2.
J
Defining a helper adverb rev, where u rev applies the verb u between y and the reversed digits of y, i.e.
+ rev y produces the next value and = rev y checks if y is a palindrome.
- Stop (without result) when
yexceeds1e7. (_2 Z: 1) - Stop processing and return
0ifyis a palindrome (1 Z: 1) - Otherwise ignore the current result and continue (
0 Z: 1)
The loop will be ended either with a value of 0, signaling a non-Lychrel number, or otherwise without result - which is an error. Catch errors and return 1 in such case.
rev =: [ ` ]: ` (|.&.(10&#.inv)) `: 6
lychrel =: _(adverb define)
stop =. {{
_2 Z: 1e7 < y
(1 Z:~ = rev) y
0
}}
(stop F. (+ rev) :: 1) f. : [:
)
See the full solution.