diff options
| author | Thomas Köhler <jean-luc@picard.franken.de> | 2023-04-07 10:01:10 +0200 |
|---|---|---|
| committer | Thomas Köhler <jean-luc@picard.franken.de> | 2023-04-07 10:01:10 +0200 |
| commit | 1d1f8699952d5136282ee4f18a0f898e71e8c7a8 (patch) | |
| tree | 03ee2fb90d7f0d7b40f92441d1f62e221cc0db86 /challenge-211 | |
| parent | 419cb48e0bd7736f9b625a9f60ce52bc77be8f7a (diff) | |
| download | perlweeklychallenge-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.txt | 1 | ||||
| -rw-r--r-- | challenge-211/jeanluc2020/blog-2.txt | 1 | ||||
| -rwxr-xr-x | challenge-211/jeanluc2020/perl/ch-1.pl | 79 | ||||
| -rwxr-xr-x | challenge-211/jeanluc2020/perl/ch-2.pl | 97 |
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; +} |
