aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2023-12-06 21:42:53 +0000
committerGitHub <noreply@github.com>2023-12-06 21:42:53 +0000
commite3ae5467460c6dda81f38390e2bd4cefa24bc781 (patch)
tree42450c601515ae21e004571002174558cb1b01cf
parent601bf322d64502e1377c6c3811f7b5e27ef2b2fa (diff)
parent72537d1aa344e47b86a48b1a6bbc351e1d89b224 (diff)
downloadperlweeklychallenge-club-e3ae5467460c6dda81f38390e2bd4cefa24bc781.tar.gz
perlweeklychallenge-club-e3ae5467460c6dda81f38390e2bd4cefa24bc781.tar.bz2
perlweeklychallenge-club-e3ae5467460c6dda81f38390e2bd4cefa24bc781.zip
Merge pull request #9208 from jeanluc2020/jeanluc-246
Add solution 246
-rw-r--r--challenge-246/jeanluc2020/blog-1.txt1
-rw-r--r--challenge-246/jeanluc2020/blog-2.txt1
-rwxr-xr-xchallenge-246/jeanluc2020/perl/ch-1.pl49
-rwxr-xr-xchallenge-246/jeanluc2020/perl/ch-2.pl147
-rwxr-xr-xchallenge-246/jeanluc2020/python/ch-1.py47
-rwxr-xr-xchallenge-246/jeanluc2020/python/ch-2.py125
6 files changed, 370 insertions, 0 deletions
diff --git a/challenge-246/jeanluc2020/blog-1.txt b/challenge-246/jeanluc2020/blog-1.txt
new file mode 100644
index 0000000000..861845124f
--- /dev/null
+++ b/challenge-246/jeanluc2020/blog-1.txt
@@ -0,0 +1 @@
+http://gott-gehabt.de/800_wer_wir_sind/thomas/Homepage/Computer/perl/theweeklychallenge-246-1.html
diff --git a/challenge-246/jeanluc2020/blog-2.txt b/challenge-246/jeanluc2020/blog-2.txt
new file mode 100644
index 0000000000..84aa5fe2ec
--- /dev/null
+++ b/challenge-246/jeanluc2020/blog-2.txt
@@ -0,0 +1 @@
+http://gott-gehabt.de/800_wer_wir_sind/thomas/Homepage/Computer/perl/theweeklychallenge-246-2.html
diff --git a/challenge-246/jeanluc2020/perl/ch-1.pl b/challenge-246/jeanluc2020/perl/ch-1.pl
new file mode 100755
index 0000000000..224607b208
--- /dev/null
+++ b/challenge-246/jeanluc2020/perl/ch-1.pl
@@ -0,0 +1,49 @@
+#!/usr/bin/perl
+# https://theweeklychallenge.org/blog/perl-weekly-challenge-246/#TASK1
+#
+# Task 1: 6 out of 49
+# ===================
+#
+# 6 out of 49 is a German lottery.
+#
+# Write a script that outputs six unique random integers from the range 1 to
+# 49.
+#
+## Output
+##
+## 3
+## 10
+## 11
+## 22
+## 38
+## 49
+#
+############################################################
+##
+## discussion
+##
+############################################################
+#
+# Collect random numbers until we have 6 of them. In case we randomly select a
+# number that we saw already, discard the number and select another random
+# number instead.
+#
+use strict;
+use warnings;
+
+my $result = {};
+
+sub next_rand {
+ my $n = int(rand(49)) + 1;
+ return $n unless $result->{$n};
+ # print "Collision, need another random number!\n";
+ return next_rand();
+}
+
+foreach(1..6) {
+ my $n = next_rand();
+ $result->{$n} = 1;
+}
+
+print join("\n", sort {$a<=>$b} keys %$result), "\n";
+
diff --git a/challenge-246/jeanluc2020/perl/ch-2.pl b/challenge-246/jeanluc2020/perl/ch-2.pl
new file mode 100755
index 0000000000..1522081a63
--- /dev/null
+++ b/challenge-246/jeanluc2020/perl/ch-2.pl
@@ -0,0 +1,147 @@
+#!/usr/bin/perl
+# https://theweeklychallenge.org/blog/perl-weekly-challenge-246/#TASK2
+#
+# Task 2: Linear Recurrence of Second Order
+# =========================================
+#
+# You are given an array @a of five integers.
+#
+# Write a script to decide whether the given integers form a linear recurrence
+# of second order with integer factors.
+#
+# A linear recurrence of second order has the form
+#
+# a[n] = p * a[n-2] + q * a[n-1] with n > 1
+#
+# where p and q must be integers.
+#
+#
+## Example 1
+##
+## Input: @a = (1, 1, 2, 3, 5)
+## Output: true
+##
+## @a is the initial part of the Fibonacci sequence a[n] = a[n-2] + a[n-1]
+## with a[0] = 1 and a[1] = 1.
+#
+## Example 2
+##
+## Input: @a = (4, 2, 4, 5, 7)
+## Output: false
+##
+## a[1] and a[2] are even. Any linear combination of two even numbers with
+## integer factors is even, too.
+## Because a[3] is odd, the given numbers cannot form a linear recurrence of
+## second order with integer factors.
+#
+## Example 3
+##
+## Input: @a = (4, 1, 2, -3, 8)
+## Output: true
+##
+## a[n] = a[n-2] - 2 * a[n-1]
+#
+############################################################
+##
+## discussion
+##
+############################################################
+#
+# We need a solution that allows for
+# p * a[0] + q * a[1] = a[2]
+# p * a[1] + q * a[2] = a[3]
+# p * a[2] + q * a[3] = a[4]
+#
+# A linear combination of a number a in term of two other numbers b and c
+# is possible if gcd(b,c) divides a; however there might be multiple
+# such combinations possible so it is not possible from one triplet of
+# numbers to determine which (if any) linear recurrence works for all
+# 5 numbers. For example (4,2,4): 1*4+0*2=4, 0*4+2*2=4, 2*4-2*2=4,
+# 3*4-4*2=4, -1*4+8*2=4, ...
+# The gcd method however allows to check whether there is any potential
+# solution at all, so let's start with that. Since the gcd of two numbers
+# can slso be combined linearly out of the two numbers I can only assume
+# the task was meant to use that, however in the general case we might have
+# to check any of the (potentially infinitely many) linear combinations for
+# whether or not their factors are suitable for the whole chain of numbers,
+# and it doesn't even hold true for the first example.
+# So we can try to find a few linear combinations from the first triplet,
+# and if any of those works for all numbers we're good.
+# As a heuristic for the range of p and q we use +/- |a|+|b| and try more or
+# less all combinations of these; since we have multiple numbers we just
+# take the maximum of those numbers * 2 instead.
+#
+use strict;
+use warnings;
+
+linear_recurrence_of_second_order(1, 1, 2, 3, 5);
+linear_recurrence_of_second_order(4, 2, 4, 5, 7);
+linear_recurrence_of_second_order(4, 1, 2, -3, 8);
+
+sub linear_recurrence_of_second_order {
+ my @a = @_;
+ my ($i, $j, $k,$l, $m) = @a;
+
+ if($k % gcd($i, $j)) {
+ return false();
+ }
+ if($l % gcd($j, $k)) {
+ return false();
+ }
+ if($m % gcd($k, $l)) {
+ return false();
+ }
+
+ my $limit = 2 * absmax(@a);
+ foreach my $p ( -$limit..$limit ) {
+ foreach my $q ( -$limit..$limit ) {
+ if($p * $i + $q * $j == $k) {
+ if($p * $j + $q * $k == $l) {
+ if($p * $k + $q * $l == $m) {
+ return true();
+ }
+ }
+ }
+ }
+ }
+ return false();
+
+}
+
+sub absmax {
+ my @list = @_;
+ my $max = abs($list[0]);
+ foreach my $elem (@list) {
+ $max = abs($elem) if abs($elem) > $max;
+ }
+ return $max;
+}
+
+sub true {
+ print "Output: true\n";
+ return 1;
+}
+
+sub false {
+ print "Output: false\n";
+ return 0;
+}
+
+sub gcd {
+ my ($x, $y) = @_;
+ if($x < 0) {
+ return gcd(-$x, $y);
+ }
+ if($y < 0) {
+ return gcd($x, -$y);
+ }
+ if($x < $y) {
+ return gcd($y, $x);
+ }
+ my $z = $x % $y;
+ if($z) {
+ return gcd($y, $z);
+ } else {
+ return $y;
+ }
+}
diff --git a/challenge-246/jeanluc2020/python/ch-1.py b/challenge-246/jeanluc2020/python/ch-1.py
new file mode 100755
index 0000000000..7a96c4e070
--- /dev/null
+++ b/challenge-246/jeanluc2020/python/ch-1.py
@@ -0,0 +1,47 @@
+#!/usr/bin/python3
+# https://theweeklychallenge.org/blog/perl-weekly-challenge-246/#TASK1
+#
+# Task 1: 6 out of 49
+# ===================
+#
+# 6 out of 49 is a German lottery.
+#
+# Write a script that outputs six unique random integers from the range 1 to
+# 49.
+#
+## Output
+##
+## 3
+## 10
+## 11
+## 22
+## 38
+## 49
+#
+############################################################
+##
+## discussion
+##
+############################################################
+#
+# Collect random numbers until we have 6 of them. In case we randomly select a
+# number that we saw already, discard the number and select another random
+# number instead.
+#
+import random
+
+result = {}
+
+def next_rand() -> int:
+ res = random.randint(1,49)
+ if res in result:
+ # collision, calculate a new random number
+ return next_rand()
+ return res
+
+for i in range(6):
+ num = next_rand()
+ result[num] = 1
+
+print("\n".join(str(x) for x in sorted(result.keys())))
+
diff --git a/challenge-246/jeanluc2020/python/ch-2.py b/challenge-246/jeanluc2020/python/ch-2.py
new file mode 100755
index 0000000000..d17d941039
--- /dev/null
+++ b/challenge-246/jeanluc2020/python/ch-2.py
@@ -0,0 +1,125 @@
+#!/usr/bin/python3
+# https://theweeklychallenge.org/blog/perl-weekly-challenge-246/#TASK2
+#
+# Task 2: Linear Recurrence of Second Order
+# =========================================
+#
+# You are given an array @a of five integers.
+#
+# Write a script to decide whether the given integers form a linear recurrence
+# of second order with integer factors.
+#
+# A linear recurrence of second order has the form
+#
+# a[n] = p * a[n-2] + q * a[n-1] with n > 1
+#
+# where p and q must be integers.
+#
+#
+## Example 1
+##
+## Input: @a = (1, 1, 2, 3, 5)
+## Output: true
+##
+## @a is the initial part of the Fibonacci sequence a[n] = a[n-2] + a[n-1]
+## with a[0] = 1 and a[1] = 1.
+#
+## Example 2
+##
+## Input: @a = (4, 2, 4, 5, 7)
+## Output: false
+##
+## a[1] and a[2] are even. Any linear combination of two even numbers with
+## integer factors is even, too.
+## Because a[3] is odd, the given numbers cannot form a linear recurrence of
+## second order with integer factors.
+#
+## Example 3
+##
+## Input: @a = (4, 1, 2, -3, 8)
+## Output: true
+##
+## a[n] = a[n-2] - 2 * a[n-1]
+#
+############################################################
+##
+## discussion
+##
+############################################################
+#
+# We need a solution that allows for
+# p * a[0] + q * a[1] = a[2]
+# p * a[1] + q * a[2] = a[3]
+# p * a[2] + q * a[3] = a[4]
+#
+# A linear combination of a number a in term of two other numbers b and c
+# is possible if gcd(b,c) divides a; however there might be multiple
+# such combinations possible so it is not possible from one triplet of
+# numbers to determine which (if any) linear recurrence works for all
+# 5 numbers. For example (4,2,4): 1*4+0*2=4, 0*4+2*2=4, 2*4-2*2=4,
+# 3*4-4*2=4, -1*4+8*2=4, ...
+# The gcd method however allows to check whether there is any potential
+# solution at all, so let's start with that. Since the gcd of two numbers
+# can slso be combined linearly out of the two numbers I can only assume
+# the task was meant to use that, however in the general case we might have
+# to check any of the (potentially infinitely many) linear combinations for
+# whether or not their factors are suitable for the whole chain of numbers,
+# and it doesn't even hold true for the first example.
+# So we can try to find a few linear combinations from the first triplet,
+# and if any of those works for all numbers we're good.
+# As a heuristic for the range of p and q we use +/- |a|+|b| and try more or
+# less all combinations of these; since we have multiple numbers we just
+# take the maximum of those numbers * 2 instead.
+#
+
+def true():
+ print("Output: true")
+ return True
+
+def false():
+ print("Output: false")
+ return False
+
+def absmax(elems: list):
+ max = abs(elems[0])
+ for elem in elems:
+ if abs(elem) > max:
+ max = abs(elem)
+ return max
+
+def gcd(x: int, y: int) -> int:
+ if x < 0:
+ return gcd(-x, y)
+ if y < 0:
+ return gcd(x, -y)
+ if x < y:
+ return gcd(y, x)
+ z = x % y
+ if z > 0:
+ return gcd(y, z)
+ return y
+
+def linear_recurrence_of_second_order(a: list) -> bool:
+ (i, j, k, l, m) = a
+
+ if k % gcd(i, j) > 0:
+ return false()
+ if l % gcd(j, k) > 0:
+ return false()
+ if m % gcd(k, l) > 0:
+ return false()
+
+ limit = 2 * absmax(a)
+
+ for p in range(-limit, 2*limit):
+ for q in range(-limit, 2*limit):
+ if p*i + q*j == k:
+ if p*j + q*k == l:
+ if p*k + q*l == m:
+ return true()
+ return false()
+
+
+linear_recurrence_of_second_order([1, 1, 2, 3, 5])
+linear_recurrence_of_second_order([4, 2, 4, 5, 7])
+linear_recurrence_of_second_order([4, 1, 2, -3, 8])