aboutsummaryrefslogtreecommitdiff
path: root/challenge-211
diff options
context:
space:
mode:
authorPaulo Custodio <pauloscustodio@gmail.com>2023-04-09 19:01:48 +0100
committerPaulo Custodio <pauloscustodio@gmail.com>2023-04-09 19:01:48 +0100
commitc5c9938bcabccd143a967d74a9fc135beeee8002 (patch)
treeeb3fd8e67019cea8e1a1b30c8147478292025796 /challenge-211
parentf03ec2c10499edf8b77ea0c3831728853c20e983 (diff)
parent4890cd1addbde634e231ba6eb4656f7eb59085e9 (diff)
downloadperlweeklychallenge-club-c5c9938bcabccd143a967d74a9fc135beeee8002.tar.gz
perlweeklychallenge-club-c5c9938bcabccd143a967d74a9fc135beeee8002.tar.bz2
perlweeklychallenge-club-c5c9938bcabccd143a967d74a9fc135beeee8002.zip
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'challenge-211')
-rw-r--r--challenge-211/0rir/raku/ch-1.raku196
-rw-r--r--challenge-211/0rir/raku/ch-2.raku91
-rw-r--r--challenge-211/carlos-oliveira/perl/ch-1.pl27
-rw-r--r--challenge-211/carlos-oliveira/perl/ch-2.pl19
-rwxr-xr-xchallenge-211/e-choroba/perl/ch-1.pl47
-rwxr-xr-xchallenge-211/e-choroba/perl/ch-2.pl72
-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
-rw-r--r--challenge-211/mark-anderson/raku/ch-2.raku16
-rw-r--r--challenge-211/peter-campbell-smith/blog.txt1
-rwxr-xr-xchallenge-211/peter-campbell-smith/perl/ch-1.pl79
-rwxr-xr-xchallenge-211/peter-campbell-smith/perl/ch-2.pl81
-rw-r--r--challenge-211/pip/perl/ch-1.pl38
-rw-r--r--challenge-211/pip/perl/ch-2.pl32
-rw-r--r--challenge-211/pip/raku/ch-1.raku39
-rw-r--r--challenge-211/pip/raku/ch-2.raku33
-rw-r--r--challenge-211/polettix/blog.txt1
-rw-r--r--challenge-211/polettix/blog1.txt1
-rw-r--r--challenge-211/polettix/perl/ch-1.pl28
-rw-r--r--challenge-211/polettix/perl/ch-2.pl52
-rw-r--r--challenge-211/polettix/raku/ch-1.raku22
-rw-r--r--challenge-211/polettix/raku/ch-2.raku48
-rw-r--r--challenge-211/robert-dicicco/julia/ch-1.jl88
-rw-r--r--challenge-211/robert-dicicco/raku/ch-1.raku76
-rw-r--r--challenge-211/robert-dicicco/ruby/ch-1.rb84
-rw-r--r--challenge-211/sgreen/README.md4
-rw-r--r--challenge-211/sgreen/blog.txt1
-rwxr-xr-xchallenge-211/sgreen/perl/ch-1.pl47
-rwxr-xr-xchallenge-211/sgreen/perl/ch-2.pl38
-rwxr-xr-xchallenge-211/sgreen/python/ch-1.py40
-rwxr-xr-xchallenge-211/sgreen/python/ch-2.py31
-rw-r--r--challenge-211/solathian/perl/ch-1.pl52
-rw-r--r--challenge-211/solathian/perl/ch-2.pl97
-rw-r--r--challenge-211/spadacciniweb/go/ch-1.go59
-rw-r--r--challenge-211/spadacciniweb/perl/ch-1.pl53
-rw-r--r--challenge-211/spadacciniweb/python/ch-1.py43
-rw-r--r--challenge-211/spadacciniweb/ruby/ch-1.rb40
39 files changed, 1845 insertions, 9 deletions
diff --git a/challenge-211/0rir/raku/ch-1.raku b/challenge-211/0rir/raku/ch-1.raku
new file mode 100644
index 0000000000..ef8770fe98
--- /dev/null
+++ b/challenge-211/0rir/raku/ch-1.raku
@@ -0,0 +1,196 @@
+#!/usr/bin/env raku
+# :vim ft=raku sw=4 expandtab # 🦋 ∅∪∩∋∈∉ ≡ ≢ «␤ » ∴
+use v6.d;
+use Test;
+
+=begin comment
+211-1: Toeplitz Matrix Submitted by: Mohammad S Anwar
+Given a matrix m x n, 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
+=end comment
+
+my @Test =
+ # shorted
+ [ [1,],], True,
+ [ [1,2,3,4,5,],], True,
+ [ [1,],[2,],[3,],[4,],[5],], True,
+
+ # examples
+ [ [4,3,2,1], [5,4,3,2], [6,5,4,3],], True,
+ [ [1,2,3], [3,2,1],], False,
+
+ # more
+ [ [1,1,1,1,], [1,1,1,1,], [1,1,1,1,], [1,1,1,1,],], True,
+ [ [1,2],[2,1],], True,
+ [ [1,2,3,], [4,1,2,], [5,4,1,],], True,
+ [ [0,1,2],[1,0,1],[2,1,0],[3,2,1],[4,3,2],], True,
+
+ [ [9,9,],
+ [9,0,],], False,
+
+ [ [0,9,],
+ [9,9,],], False,
+
+ [ [0,1,9],
+ [1,0,1],
+ [9,1,0],], True,
+
+ [ [9,1,9],
+ [1,0,1],
+ [9,1,0],], False,
+
+ [ [0,9,9],
+ [1,0,1],
+ [9,1,0],], False,
+
+ [ [0,1,9],
+ [9,0,1],
+ [9,1,0],], False,
+
+ [ [0,1,9],
+ [1,9,1],
+ [9,1,0],], False,
+
+ [ [0,1,9],
+ [1,0,9],
+ [9,1,0],], False,
+
+ [ [0,1,9],
+ [1,0,1],
+ [9,9,0],], False,
+
+ [ [0,1,9],
+ [1,0,1],
+ [9,1,9],], False,
+
+ [ [0,2,],
+ [1,0,],
+ [2,1,],
+ [0,2,],], True,
+
+ [ [0,1,5,6,],
+ [1,0,1,5,],
+ [2,1,0,1,],
+ [6,2,1,0,],], True,
+
+ [ [0,1,2,6,],
+ [1,0,1,2,],
+ [2,1,0,1,],
+ [6,2,1,0,],], True,
+
+ [ [0,1,5,6,7,],
+ [1,0,1,5,6,],
+ [2,1,0,1,5,],
+ [0,2,1,0,1,],], True,
+
+ [ [0,1,5,6,7,],
+ [1,0,1,5,6,],
+ [2,1,0,1,5,],
+ [0,2,1,0,1,],], True,
+;
+
+my @Dead =
+ [ ],
+ [ [],],
+ [ [1,],[],],
+ [ [1,],[1,2],],
+ [ [4,3,2,1], [5,4,3,2], [5,4,3],],
+;
+
+plan @Test + @Dead;
+
+
+sub is-toeplitz( @a -->Bool){
+
+ invalid( @a);
+
+ my ($cols, $rows) = @a[0].end, @a.end;
+
+ return True if $cols == 0 or $rows == 0; # very short diagonals
+
+ my $o = [ $rows-1, 0];
+
+ loop {
+ return False unless $o.&diag;
+ $o.&next-diag;
+ last if $o.&last-diag;
+ }
+ return True;
+
+ # --- not reached ----
+
+ constant R = 0;
+ constant C = 1;
+
+ sub val( $d -->Any){ @a[ $d[R]][ $d[C]] }
+
+ sub next-diag( $d is rw -->Array){ # alter dyad to index next diag origin
+ when $d[R] > 0 { --$d[R]; $d }
+ when $d[R] == 0 { ++$d[C]; $d }
+ die 'not reached ( stupid programmer either way)';
+ }
+
+ sub last-diag( $d -->Bool){ $d[R] == 0 and $d[C] == $cols}
+
+ sub diag( $d -->Bool){
+ my $ref = $d.&val;
+ my ($R, $C) = 1 + $d[R], 1 + $d[C];
+ while $R ≤ $rows and $C ≤ $cols {
+ return False if $ref ≠ @a[$R++][$C++];
+ }
+ return True;
+ }
+ sub invalid( @a -->Nil){
+ when @a ~~ Empty { die "Empty" }
+ when @a.any ~~ Empty { die "Empty elem" }
+ with @a[1..^@a].first( {.end !~~ @a[0].end} ) {
+ die "Misshapened"; }
+ return;
+ }
+}
+
+for @Dead -> @in {
+ dies-ok { is-toeplitz( @in )},
+ "Died-ok: Empty, Empty elem, or misshapened";
+}
+for @Test -> @in, $exp {
+ lives-ok { is-toeplitz( @in )},
+ "Lives-ok: Empty, Empty elem, or misshapened";
+ is is-toeplitz(@in), $exp, "$exp <- @in.raku()";
+}
+done-testing;
+
+
+my @matrix = [ [0,1,5,6,7,],
+ [1,0,1,5,6,],
+ [2,1,0,1,5,],
+ [0,2,1,0,1,],];
+
+sub matrix-say( @m is copy ) {
+ for @matrix -> $row is rw {
+ $row = $row.join( ",");
+ }
+ print "\nInput @matrix = [ [";
+ print @matrix.join: "],\n [";
+ print "],\n ]\n";
+}
+
+matrix-say( @matrix);
+say "Output: ", is-toeplitz( @matrix);
+
+exit;
+
diff --git a/challenge-211/0rir/raku/ch-2.raku b/challenge-211/0rir/raku/ch-2.raku
new file mode 100644
index 0000000000..3828fa95c6
--- /dev/null
+++ b/challenge-211/0rir/raku/ch-2.raku
@@ -0,0 +1,91 @@
+#!/usr/bin/env raku
+# :vim ft=raku sw=4 expandtab # 🦋 ∅∪∩∋∈∉ ≡ ≢ «␤ » ∴
+use v6.d;
+use Test;
+
+=begin comment
+211-2: Split Same Average Submitted by: Mohammad S Anwar
+Given an array of integers, find out if the array can be split into two
+separate arrays whose averages 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
+=end comment
+
+my @Test =
+ # shorts -- atomic
+ [ ], False,
+ [ 1], False,
+ # given examples
+ [ 1,3], False,
+ [ 2,3,6,7, 1,4,5,8], True,
+ # more
+ [ 11 xx 111], True,
+ [ 0,0,0,0,0], True,
+ [ 1,1], True,
+ [ 1,2], False,
+ [ 1,2,4], False,
+ [ 2,2,3], False,
+ [ 1,-1], False,
+ [ 1,14,15], False,
+ [ 1,14, 0,15], True,
+ [ 0,0,1,14,15], False,
+ [ 0,1,14, 0,0,15], True,
+ [ 1,2,3,12,13,14,15], False,
+ [ 0,7, 1,2,3,4,5,6], True,
+ [ 0,1,1,2,3,4,5,6,7], False,
+ [ 1,4, 2,3], True,
+ [ 2, 0,1,3,4], True,
+ [ 1,4,5,7, 0,2,3,6,8], True,
+ [ -2, -1,-1,0], True,
+ [ -3,-2,-1,1], False,
+ [ -3…0], True,
+ [ -3…1], True,
+ [ -1,0,2,6,7, 1,1,3,4,5], True,
+ [ -1,-1,2,6,7, 0,1,3,4,5], True,
+ [ -1,1,2,3,4,5,6,7], False,
+ [ -10…10], True,
+ [ -9…10], True,
+ [ 1…12], True,
+ [ 0…12], True,
+ [ -2…1], True,
+ [ -4…4], True,
+;
+
+# return True if so 'subset.elems × other.sum == subset.sum × other.elems'
+# is found, else False.
+multi same-average-parts2( @in where *.elems ≤ 1 -->Bool ){ False }
+multi same-average-parts2( @in -->Bool){
+
+ my Int $total = [+] @in;
+
+ my $prev;
+ for 1..(@in.elems div 2) -> $a-elems {
+ for @in.combinations( $a-elems).sort -> $a {
+ my $b-val = $a-elems × ($total - [+] $a);
+
+ if $b-val == ([+] $a) × ( @in.elems - $a-elems) {
+ return True;
+ } } }
+ return False;
+}
+
+plan @Test/2;
+
+for @Test -> @t, $exp {
+ is same-average-parts2( @t), $exp, "$exp <- @t[]";
+}
+done-testing;
+
+my $ints = @Test[*-2];
+say "\nInput: \$ints = $ints[]"
+ ,"\nOutput: &same-average-parts2($ints)";
+
+exit;
diff --git a/challenge-211/carlos-oliveira/perl/ch-1.pl b/challenge-211/carlos-oliveira/perl/ch-1.pl
new file mode 100644
index 0000000000..bfd6351111
--- /dev/null
+++ b/challenge-211/carlos-oliveira/perl/ch-1.pl
@@ -0,0 +1,27 @@
+use strict;
+use warnings;
+use v5.36;
+
+use Test::More;
+use List::Util qw(uniq);
+
+sub is_toeplitz_matrix (@matrix) {
+ my $cols = $matrix[0]->@*;
+ for my $i (0..$#matrix) {
+ my @diagonal = uniq map { $i < $cols ? $_->[$i++] : () } @matrix;
+ return 0 unless @diagonal == 1;
+ }
+ return 1;
+}
+
+is is_toeplitz_matrix(
+ [4, 3, 2, 1],
+ [5, 4, 3, 2],
+ [6, 5, 4, 3]
+), 1;
+is is_toeplitz_matrix(
+ [1, 2, 3],
+ [3, 2, 1]
+), 0;
+
+done_testing;
diff --git a/challenge-211/carlos-oliveira/perl/ch-2.pl b/challenge-211/carlos-oliveira/perl/ch-2.pl
new file mode 100644
index 0000000000..421b8e94d7
--- /dev/null
+++ b/challenge-211/carlos-oliveira/perl/ch-2.pl
@@ -0,0 +1,19 @@
+use strict;
+use warnings;
+use v5.36;
+
+use Test::More;
+use Algorithm::Combinatorics qw(partitions);
+use List::Util qw(any sum uniqnum);
+use builtin qw(true false);
+
+sub can_be_split_with_same_average (@array) {
+ return any { $_->@* == 1 }
+ map { [ uniqnum map sum($_->@*) / $_->@*, $_->@* ] }
+ partitions \@array, 2;
+}
+
+is can_be_split_with_same_average(1, 2, 3, 4, 5, 6, 7, 8), true;
+is can_be_split_with_same_average(1, 3), false;
+
+done_testing;
diff --git a/challenge-211/e-choroba/perl/ch-1.pl b/challenge-211/e-choroba/perl/ch-1.pl
new file mode 100755
index 0000000000..90ae514e7b
--- /dev/null
+++ b/challenge-211/e-choroba/perl/ch-1.pl
@@ -0,0 +1,47 @@
+#! /usr/bin/perl
+use warnings;
+use strict;
+use experimental qw( signatures );
+
+sub toeplitz_matrix($m) {
+ my $x = 0;
+ my $y = $#$m;
+ while ($x <= $#{ $m->[0] }) {
+ my ($u, $v) = ($x, $y);
+ while (++$u <= $#{ $m->[0] } && ++$v <= $#$m) {
+ return if $m->[$v][$u] != $m->[$y][$x];
+ }
+ } continue {
+ if ($y) {
+ --$y;
+ } else {
+ ++$x;
+ }
+ }
+ return 1
+}
+
+use Test::More tests => 4;
+
+ok toeplitz_matrix([ [4, 3, 2, 1],
+ [5, 4, 3, 2],
+ [6, 5, 4, 3],
+ ]), 'Example 1';
+
+ok ! toeplitz_matrix([ [1, 2, 3],
+ [3, 2, 1],
+ ]), 'Example 2';
+
+ok toeplitz_matrix([[1]]), '1x1';
+ok toeplitz_matrix([[1,2,3,4,5,6,7],
+ [8,1,2,3,4,5,6],
+ [9,8,1,2,3,4,5],
+ [10,9,8,1,2,3,4],
+ [11,10,9,8,1,2,3],
+ [12,11,10,9,8,1,2],
+ [13,12,11,10,9,8,1],
+ [14,13,12,11,10,9,8],
+ [15,14,13,12,11,10,9],
+ [16,15,14,13,12,11,10],
+ [17,16,15,14,13,12,11],
+ ]), 'Larger';
diff --git a/challenge-211/e-choroba/perl/ch-2.pl b/challenge-211/e-choroba/perl/ch-2.pl
new file mode 100755
index 0000000000..02942855f9
--- /dev/null
+++ b/challenge-211/e-choroba/perl/ch-2.pl
@@ -0,0 +1,72 @@
+#! /usr/bin/perl
+use warnings;
+use strict;
+use experimental qw( signatures );
+
+use List::Util qw{ sum };
+
+sub split_same_average_brute_force(@list) {
+ my $avg = sum(@list) / @list;
+ my @mask = (0) x @list;
+ $mask[-1] = 1;
+ while (1) {
+ my $s = sum(@list[grep $mask[$_], 0 .. $#mask]);
+ return 1 if abs($s / (grep $_, @mask) - $avg) < 1e-9;
+
+ my $pos = $#mask;
+ while ($mask[$pos]) {
+ $mask[$pos] = 0;
+ return if --$pos < 1;
+ }
+ $mask[$pos] = 1;
+ }
+
+}
+
+sub split_same_average(@list) {
+ my $sum = sum(@list);
+ my $avg = $sum / @list;
+ my $max_length = (@list + 1) / 2;
+ --$max_length if $max_length >= @list - 1;
+
+ my %possible; # {sum}{length}
+ $possible{0}{0} = 1;
+ for my $e (@list) {
+ # Sort is needed so we don't process the added sum again in
+ # the same step.
+ for my $s (sort { $b <=> $a } keys %possible) {
+ for my $length (keys %{ $possible{$s} }) {
+ next if $length == @list - 1;
+
+ $possible{ $s + $e }{ $length + 1 } = 1;
+ return 1 if abs(($s + $e) / ($length+1) - $avg) < 1e-9;
+ }
+ }
+ }
+ return
+}
+
+use Test::More;
+
+ok split_same_average(1, 2, 3, 4, 5, 6, 7, 8), 'Example 1';
+ok ! split_same_average(1, 3), 'Example 2';
+
+ok split_same_average(-2, 0, 2), 'Avg 0';
+ok split_same_average(1, 5, 5, 1), 'Duplicates';
+
+for (1 .. 200) {
+ my @list = map int rand 20, 1 .. 2 + rand 10;
+ is split_same_average(@list), split_same_average_brute_force(@list),
+ "same @list";
+}
+
+my @l = map int rand 50, 1 .. 12;
+is split_same_average(@l), split_same_average_brute_force(@l),
+ "same @l";
+done_testing();
+
+use Benchmark qw{ cmpthese };
+cmpthese(-3, {
+ brute_force => sub { split_same_average_brute_force(@l) },
+ fast => sub { split_same_average(@l) },
+});
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;
+}
diff --git a/challenge-211/mark-anderson/raku/ch-2.raku b/challenge-211/mark-anderson/raku/ch-2.raku
index 255ada41f4..9b88288ee3 100644
--- a/challenge-211/mark-anderson/raku/ch-2.raku
+++ b/challenge-211/mark-anderson/raku/ch-2.raku
@@ -1,6 +1,11 @@
#!/usr/bin/env raku
use Test;
+# This is a do-over after reading other solutions.
+# Jorg Sommrey and W. Luis Mochan explained that if one subset's average
+# equals the average of the whole list then the other subset will have
+# the same average.
+
ok split-same-avg(1,2,3,4,5,6,7,8); # [1 8] [2 3 4 5 6 7]
nok split-same-avg(1,3);
ok split-same-avg(3,3,5,5,5,2,2,1); # [2 3 3 5] [1 2 5 5]
@@ -8,14 +13,11 @@ nok split-same-avg(5,5,5,2,2,1);
sub split-same-avg(*@nums)
{
- for (^@nums).combinations(1..@nums.elems div 2) -> @a is copy
- {
- my @b = (^@nums (-) @a).keys;
+ my $avg = @nums.sum / @nums.elems;
- @a = @nums[@a];
- @b = @nums[@b];
-
- return True if @a.sum / @a.elems == @b.sum / @b.elems
+ for (^@nums).combinations(1..@nums.elems div 2) -> @a
+ {
+ return True if @nums[@a].sum / @nums[@a].elems == $avg
}
return False
diff --git a/challenge-211/peter-campbell-smith/blog.txt b/challenge-211/peter-campbell-smith/blog.txt
new file mode 100644
index 0000000000..8ca8f03329
--- /dev/null
+++ b/challenge-211/peter-campbell-smith/blog.txt
@@ -0,0 +1 @@
+http://ccgi.campbellsmiths.force9.co.uk/challenge/211
diff --git a/challenge-211/peter-campbell-smith/perl/ch-1.pl b/challenge-211/peter-campbell-smith/perl/ch-1.pl
new file mode 100755
index 0000000000..bd20e4b8ce
--- /dev/null
+++ b/challenge-211/peter-campbell-smith/perl/ch-1.pl
@@ -0,0 +1,79 @@
+#!/usr/bin/perl
+
+use v5.16; # The Weekly Challenge - 2023-04-03
+use utf8; # Week 211 task 1 - Toeplitz matrix
+use strict; # Peter Campbell Smith
+use warnings; # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge
+
+toeplitz_matrix( [[4, 3, 2, 1],
+ [5, 4, 3, 2],
+ [6, 5, 4, 3]] );
+
+toeplitz_matrix( [[4, 3, 2, 1],
+ [5, 4, 3, 2],
+ [6, 5, 4, 7]] );
+
+toeplitz_matrix( [[37.1, 114, 0, -23.65, 5, 3],
+ [-40, 37.1, 114, 0, -23.65, 5],
+ [-19, -40, 37.1, 114, 0, -23.65],
+ [3, -19, -40, 37.1, 114, 0],
+ [55, 3, -19, -40, 37.1, 114],
+ [0, 55, 3, -19, -40, 37.1],
+ [999, 0, 55, 3, -19, -40]] );
+
+toeplitz_matrix( [[6, 0, 0, 0, 6],
+ [0, 0, 6, 0, 0],
+ [6, 0, 0, 0, 6]] );
+
+sub toeplitz_matrix {
+
+ my($m, $r, $c, $x, $good);
+
+ $m = $_[0];
+
+ # loop over rows and then columns
+ ROW: for $r (1 .. scalar @$m - 1) {