aboutsummaryrefslogtreecommitdiff
path: root/challenge-211
diff options
context:
space:
mode:
authorThomas Köhler <jean-luc@picard.franken.de>2023-04-07 10:01:10 +0200
committerThomas Köhler <jean-luc@picard.franken.de>2023-04-07 10:01:10 +0200
commit1d1f8699952d5136282ee4f18a0f898e71e8c7a8 (patch)
tree03ee2fb90d7f0d7b40f92441d1f62e221cc0db86 /challenge-211
parent419cb48e0bd7736f9b625a9f60ce52bc77be8f7a (diff)
downloadperlweeklychallenge-club-1d1f8699952d5136282ee4f18a0f898e71e8c7a8.tar.gz
perlweeklychallenge-club-1d1f8699952d5136282ee4f18a0f898e71e8c7a8.tar.bz2
perlweeklychallenge-club-1d1f8699952d5136282ee4f18a0f898e71e8c7a8.zip
Add solution for week 211.
Signed-off-by: Thomas Köhler <jean-luc@picard.franken.de>
Diffstat (limited to 'challenge-211')
-rw-r--r--challenge-211/jeanluc2020/blog-1.txt1
-rw-r--r--challenge-211/jeanluc2020/blog-2.txt1
-rwxr-xr-xchallenge-211/jeanluc2020/perl/ch-1.pl79
-rwxr-xr-xchallenge-211/jeanluc2020/perl/ch-2.pl97
4 files changed, 178 insertions, 0 deletions
diff --git a/challenge-211/jeanluc2020/blog-1.txt b/challenge-211/jeanluc2020/blog-1.txt
new file mode 100644
index 0000000000..0f0f93f599
--- /dev/null
+++ b/challenge-211/jeanluc2020/blog-1.txt
@@ -0,0 +1 @@
+http://gott-gehabt.de/800_wer_wir_sind/thomas/Homepage/Computer/perl/theweeklychallenge-211-1.html
diff --git a/challenge-211/jeanluc2020/blog-2.txt b/challenge-211/jeanluc2020/blog-2.txt
new file mode 100644
index 0000000000..bd76722861
--- /dev/null
+++ b/challenge-211/jeanluc2020/blog-2.txt
@@ -0,0 +1 @@
+http://gott-gehabt.de/800_wer_wir_sind/thomas/Homepage/Computer/perl/theweeklychallenge-211-2.html
diff --git a/challenge-211/jeanluc2020/perl/ch-1.pl b/challenge-211/jeanluc2020/perl/ch-1.pl
new file mode 100755
index 0000000000..c68d360ce9
--- /dev/null
+++ b/challenge-211/jeanluc2020/perl/ch-1.pl
@@ -0,0 +1,79 @@
+#!/usr/bin/perl
+# https://theweeklychallenge.org/blog/perl-weekly-challenge-211/#TASK1
+#
+# Task 1: Toeplitz Matrix
+# =======================
+#
+# You are given a matrix m x n.
+#
+# Write a script to find out if the given matrix is Toeplitz Matrix.
+#
+## A matrix is Toeplitz if every diagonal from top-left to bottom-right has the
+## same elements.
+#
+## Example 1
+##
+## Input: @matrix = [ [4, 3, 2, 1],
+## [5, 4, 3, 2],
+## [6, 5, 4, 3],
+## ]
+## Output: true
+#
+## Example 2
+##
+## Input: @matrix = [ [1, 2, 3],
+## [3, 2, 1],
+## ]
+## Output: false
+#
+############################################################
+##
+## discussion
+##
+############################################################
+#
+# We just need to walk all diagonals and check if all numbers are
+# the same. But actually it's easier to walk the matrix and check
+# whether the element to the right bottom of the current one differs
+# from the current one. When we do that everywhere we can know
+# whether all diagonals have the same number everywhere as well,
+# so let's do that.
+
+toeplitz([ [4, 3, 2, 1],
+ [5, 4, 3, 2],
+ [6, 5, 4, 3] ]);
+toeplitz([ [1, 2, 3],
+ [3, 2, 1] ]);
+
+sub toeplitz {
+ my $matrix = shift;
+ die "Not a matrix" unless is_matrix($matrix);
+ # get the dimensions of the matrix
+ my $lines = scalar(@$matrix);
+ my $columns = scalar(@{$matrix->[0]});
+ # for each line and column except the last one, compare the element
+ # at that position and the one on the right bottom of it
+ foreach my $i (0..$lines-2) {
+ foreach my $j (0..$columns-2) {
+ my $this_element = $matrix->[$i]->[$j];
+ my $next_diagonal_element = $matrix->[$i+1]->[$j+1];
+ if ($this_element != $next_diagonal_element) {
+ print "Output: false\n";
+ return;
+ }
+ }
+ }
+ print "Output: true\n";
+}
+
+# helper function to check if we actually have a matrix
+sub is_matrix {
+ my $matrix = shift;
+ return 0 unless ref($matrix) eq "ARRAY";
+ my $columns = scalar(@{$matrix->[0]});
+ foreach my $line (@$matrix) {
+ return 0 unless scalar(@$line) == $columns;
+ }
+ return 1;
+}
+
diff --git a/challenge-211/jeanluc2020/perl/ch-2.pl b/challenge-211/jeanluc2020/perl/ch-2.pl
new file mode 100755
index 0000000000..10407b7a85
--- /dev/null
+++ b/challenge-211/jeanluc2020/perl/ch-2.pl
@@ -0,0 +1,97 @@
+#!/usr/bin/perl
+# https://theweeklychallenge.org/blog/perl-weekly-challenge-211/#TASK2
+#
+# Task 2: Split Same Average
+# ==========================
+#
+# You are given an array of integers.
+#
+# Write a script to find out if the given can be split into two separate arrays whose average are the same.
+#
+## Example 1:
+##
+## Input: @nums = (1, 2, 3, 4, 5, 6, 7, 8)
+## Output: true
+##
+## We can split the given array into (1, 4, 5, 8) and (2, 3, 6, 7).
+## The average of the two arrays are the same i.e. 4.5.
+#
+## Example 2:
+##
+## Input: @list = (1, 3)
+## Output: false
+#
+############################################################
+##
+## discussion
+##
+############################################################
+#
+# This is basically a problem on how to create all possible
+# combinations and checking if any of these allows for the
+# same average
+
+use strict;
+use warnings;
+use List::Util qw(sum);
+
+split_same_average(1, 2, 3, 4, 5, 6, 7, 8);
+split_same_average(1, 3);
+
+sub split_same_average {
+ my @list = @_;
+ print "Input: (" . join(", ", @list) . ")\n";
+ if(has_matching_split([@list], [], [])) {
+ print "Output: true\n";
+ } else {
+ print "Output: false\n";
+ }
+}
+
+# check if the rest of the current list, with two partially
+# filled lists from the previous elements, can still be turned
+# into two lists that have the same average
+# so we create all possible combinations step by step, if we have
+# found one we check if it has lead us to two lists of the same
+# average, and otherwise return a non-true value (which will lead
+# to the next recursive call)
+sub has_matching_split {
+ my ($rest, $list1, $list2) = @_;
+ if(@$rest) {
+ # we still have some elements to distribute among the two
+ # lists, so we get the first element of this remainder
+ my $first = shift @$rest;
+ # if by adding this to the first partial list we can achieve
+ # a combination where both lists have the same average, we can
+ # finish searching and return 1
+ if(has_matching_split([@$rest], [@$list1, $first], [@$list2])) {
+ return 1;
+ }
+ # same is true if we can achieve a good combination by adding the
+ # element to the second partial list
+ if(has_matching_split([@$rest], [@$list1], [@$list2, $first])) {
+ return 1;
+ }
+ # if we didn't succeed either way, we can't find any matching combination
+ # that leads to two arrays with the same average, so we return 0
+ return 0;
+ } else {
+ # we have distributed all elements to the two lists, so if both
+ # lists are non-empty and share the same average we have found a
+ # solution
+ if(@$list1 && @$list2 && average(@$list1) == average(@$list2)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+# of course we need a helper function to calculate the average of all
+# elements of a list
+sub average {
+ my @list = @_;
+ my $count = @list;
+ return undef unless $count;
+ my $sum = sum @list;
+ return $sum / $count;
+}