aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2021-11-08 00:11:58 +0000
committerGitHub <noreply@github.com>2021-11-08 00:11:58 +0000
commita64e00989ef6e5a78aae38d8cd95b56385934eca (patch)
tree4ff3871baf272badb3a99ee7ca59334797add017
parent350a7ebb4eee4a4636674e14431d195e68b49f27 (diff)
parent4a6b253d19ce3c44af125f2e41ddb5a6a259180f (diff)
downloadperlweeklychallenge-club-a64e00989ef6e5a78aae38d8cd95b56385934eca.tar.gz
perlweeklychallenge-club-a64e00989ef6e5a78aae38d8cd95b56385934eca.tar.bz2
perlweeklychallenge-club-a64e00989ef6e5a78aae38d8cd95b56385934eca.zip
Merge pull request #5175 from dcw803/master
imported my solutions to this week's tasks.. task 2 was a bit strange
-rw-r--r--challenge-137/duncan-c-white/README96
-rwxr-xr-xchallenge-137/duncan-c-white/perl/ch-1.pl82
-rwxr-xr-xchallenge-137/duncan-c-white/perl/ch-2.pl100
3 files changed, 228 insertions, 50 deletions
diff --git a/challenge-137/duncan-c-white/README b/challenge-137/duncan-c-white/README
index c41627048b..a9b09917c6 100644
--- a/challenge-137/duncan-c-white/README
+++ b/challenge-137/duncan-c-white/README
@@ -1,77 +1,73 @@
-TASK #1 - Two Friendly
+TASK #1 - Long Year
-You are given 2 positive numbers, $m and $n.
+Write a script to find all the years between 1900 and 2100 which is a Long Year.
-Write a script to find out if the given two numbers are Two Friendly.
+ A year is Long if it has 53 weeks.
-Two positive numbers, m and n are two friendly when gcd(m, n) = 2 ^
-p where p > 0. The greatest common divisor (gcd) of a set of numbers
-is the largest positive number that divides all the numbers in the set
-without remainder.
+For more information about Long Year, please refer to
-Example 1
-
- Input: $m = 8, $n = 24
- Output: 1
-
- Reason: gcd(8,24) = 8 => 2 ^ 3
-
-Example 2
-
- Input: $m = 26, $n = 39
- Output: 0
+https://en.wikipedia.org/wiki/ISO_week_date#Weeks_per_year
- Reason: gcd(26,39) = 13
+Expected Output
-Example 3
+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
- Input: $m = 4, $n = 10
- Output: 1
+MY NOTES: Pretty easy. Especially using the p(year) and weeks(year) functions given,
+won't even need a date manipulation module..
- Reason: gcd(4,10) = 2 => 2 ^ 1
-MY NOTES: Pretty easy. Euclid's GCD algorithm, then check if the result is a power of 2.
+TASK #2 - Lychrel Number
+You are given a number, 10 <= $n <= 1000.
-TASK #2 - Fibonacci Sequence
+Write a script to find out if the given number is Lychrel number;
+output 1 if it is, and zero if it is not. To keep the task simple, we impose the following rules:
-You are given a positive number $n.
+a. Stop and return 1 if the number of iterations reached 500.
+b. Stop and return 1 if you end up with number >= 10_000_000.
-Write a script to find how many different sequences you can create using
-Fibonacci numbers where the sum of unique numbers in each sequence are
-the same as the given number.
+According to wikipedia:
- Fibonacci Numbers: 1,2,3,5,8,13,21,34,55,89,..
+ 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 = 16
- Output: 4
+ Input: $n = 56
+ Output: 0
- Reason: There are 4 possible sequences that can be created using Fibonacci numbers
- i.e. (3 + 13), (1 + 2 + 13), (3 + 5 + 8) and (1 + 2 + 5 + 8).
+ After 1 iteration, we found palindrome number.
+ 56 + 65 = 121
Example 2
- Input: $n = 9
- Output: 2
+ Input: $n = 57
+ Output: 0
- Reason: There are 2 possible sequences that can be created using Fibonacci numbers
- i.e. (1 + 3 + 5) and (1 + 8).
+ After 2 iterations, we found palindrome number.
+ 57 + 75 = 132
+ 132 + 231 = 363
Example 3
- Input: $n = 15
- Output: 2
-
- Reason: There are 2 possible sequences that can be created using Fibonacci numbers
- i.e. (2 + 5 + 8) and (2 + 13).
+ Input: $n = 59
+ Output: 0
-MY NOTES: Pretty easy - find subsets of the first few Fibonacci numbers that sum to N.
-How many Fibonacci numbers should we consider? Those <= N. Then, how do we sum subsets
-of them? Two obvious ways:
+ After 3 iterations, we found palindrome number.
+ 59 + 95 = 154
+ 154 + 451 = 605
+ 605 + 506 = 1111
-1. recursive function, iterating over the Fibonacci values: each value is either in the
- subset or not, try both possibilities.
-2. binary-counting method, iterate over every combination C from 1 .. 2**(number values)-1,
- then sum up only the elements where the corresponding bit in C is true.
+MY NOTES: Sounds pretty easy. The strangest thing about this question
+is that the Wikipedia page has that (without the artificial constraints)
+noone found a definite Lychrel base 10 number. So any "Output: 1" entries
+we can find (such as 89) are caused by sequences violating one or other
+of the constraints.
diff --git a/challenge-137/duncan-c-white/perl/ch-1.pl b/challenge-137/duncan-c-white/perl/ch-1.pl
new file mode 100755
index 0000000000..a0adda2685
--- /dev/null
+++ b/challenge-137/duncan-c-white/perl/ch-1.pl
@@ -0,0 +1,82 @@
+#!/usr/bin/perl
+#
+# TASK #1 - Long Year
+#
+# 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.
+#
+# For more information about Long Year, please refer to
+#
+# https://en.wikipedia.org/wiki/ISO_week_date#Weeks_per_year
+#
+# 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
+#
+# MY NOTES: Pretty easy. Especially using the p(year) and weeks(year) functions given,
+# won't even need a date manipulation module..
+#
+
+use strict;
+use warnings;
+use feature 'say';
+use Getopt::Long;
+use Function::Parameters;
+#use Data::Dumper;
+
+
+my $debug=0;
+die "Usage: long-year\n" unless
+ GetOptions( "debug"=>\$debug ) && @ARGV==0;
+
+#
+# my $dow = dow_31stdec( $year );
+# Return the Dow (0..6, 0 is Sunday, 6 is Saturday) of 31st Dec in $year.
+# Wikipedia's P() function:
+#
+fun dow_31stdec( $year )
+{
+ my $x = $year + int($year/4) - int($year/100) + int($year/400);
+ return $x % 7;
+}
+
+
+#
+# my $weeks = weeksinyear( $year );
+# How many weeks does year $year have? 52 or 53..
+#
+fun weeksinyear( $year )
+{
+ my $result = 52;
+ $result++ if dow_31stdec( $year ) == 4 # current year ends on Thursday
+ || dow_31stdec( $year-1) == 3; # previous year ends on Wednesday
+ return $result;
+}
+
+#my @dow = qw(Sun Mon Tue Wed Thu Fri Sat);
+
+my @result;
+foreach my $y (1900..2100)
+{
+ #my $dow = dow_31stdec( $y );
+ #say "31st dec $y is a $dow[$dow]";
+ my $weeks = weeksinyear( $y );
+ #say "$y has $weeks weeks";
+ next if $weeks == 52;
+ push @result, $y;
+}
+
+while( @result > 4 )
+{
+ say join( ', ', @result[0..4] ).',';
+ splice( @result, 0, 5 );
+}
+say join( ', ', @result );
diff --git a/challenge-137/duncan-c-white/perl/ch-2.pl b/challenge-137/duncan-c-white/perl/ch-2.pl
new file mode 100755
index 0000000000..546e0a3abe
--- /dev/null
+++ b/challenge-137/duncan-c-white/perl/ch-2.pl
@@ -0,0 +1,100 @@
+#!/usr/bin/perl
+#
+# TASK #2 - Lychrel Number
+#
+# You are given a number, 10 <= $n <= 1000.
+#
+# Write a script to find out if the given number is Lychrel number;
+# output 1 if it is, and zero if it is not. To keep the task simple, we impose the following rules:
+#
+# a. Stop and return 1 if the number of iterations reached 500.
+# b. Stop and return 1 if you end up with number >= 10_000_000.
+#
+# 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
+#
+# MY NOTES: Sounds pretty easy.
+#
+
+use strict;
+use warnings;
+use feature 'say';
+use Function::Parameters;
+use Getopt::Long;
+use Data::Dumper;
+
+my $debug = 0;
+
+die "Usage: is-lychrel [-d|--debug] N\n"
+ unless GetOptions( "debug"=>\$debug ) && @ARGV==1;
+my $n = shift @ARGV;
+die "$n is out of range 10..1000\n" if $n < 10 || $n > 1000;
+
+
+#
+# my @steps = get_to_palindrome( $n );
+# Try to find a sequence of n + reverse(n) values leading to a palindrome,
+# if you find one in less than 500 steps, with no intermediate value
+# exceeding 10,000,000, then return the sequence of steps.
+# If you can't find such a sequence, return ().
+#
+fun get_to_palindrome( $n )
+{
+ my @result;
+ for( my $nit = 0; $nit<500; $nit++ )
+ {
+ return () if $n > 10000000; # intermediate value too big
+ my $r = reverse($n);
+ my $msg = sprintf( "%4d + %4d = %d", $n, $r, $n+$r );
+ push @result, $msg;
+ say "debug: $msg" if $debug;
+ $n += $r;
+ return @result if $n == reverse($n); # found a palindrome
+ }
+ return (); # too many iterations
+}
+
+
+my @seq = get_to_palindrome( $n );
+say "Input: $n";
+print "Output: ";
+if( @seq )
+{
+ say 0;
+ my $steps = @seq;
+ say "\nAfter $steps iterations, we found a palindrome:";
+ say for @seq;
+} else
+{
+ say 1;
+}