I’ve been doing the Weekly
Challenges. The
latest
involved matrix evaluation and integer searching. (Note that this
closes today.)
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.
I don't see any obvious short-cuts here.
Perl:
sub toeplitzmatrix($a) {
my $ym = $#{$a};
my $xm = $#{$a->[0]};
Finding one non-consistent diagonal will be enough for a false
return. But we have to check all of them to get a true
one.
my $toeplitz = 1;
The X coordinate of the start of every conceivable diagonal runs from -X to +Y.
foreach my $xb ((1 - $xm)..($ym - 1)) {
my $init = 1;
my $tv = 0;
Each possible entry on that diagonal:
foreach my $x ($xb .. $xb + $xm) {
…may not exist.
if ($x >= 0 && $x <= $xm) {
Similarly, the Y coordinate may not exist.
my $y = $x - $xb;
If they do, though, store the value if it's the first one we've met.
if ($y >= 0 && $y <= $ym) {
if ($init) {
$init = 0;
$tv = $a->[$y][$x];
Otherwise, if it doesn't match that stored value, drop out with a
false
return.
} elsif ($a->[$y][$x] != $tv) {
$toeplitz = 0;
last;
}
}
}
}
unless ($toeplitz) {
last;
}
}
return $toeplitz;
}
Task 2: Split Same Average
You are given an array of integers.
Write a script to find out if the given array can be split into two
separate arrays whose average are the same.
This means generating combinations, and I finally bit the bullet and
wrote combination generators for the languages that didn't have them
built in (Kotlin, Lua and JavaScript). (I'm not claiming that these
don't exist in libraries, but they're not trivially available.)
Raku has a Rat
type for rational fractions, but otherwise I used
floating-point equality tests. (Rust does too, but I didn't know about
it.)
In Rust:
fn splitsameaverage(a: Vec<i32>) -> bool {
Pre-calculate the sum of the list, and store the numnber of entries in it.
let ss = a.iter().sum::<i32>();
let ml = a.len();
I'll be checking each combination up to half the length (rounded down).
let mx = ml / 2;
One positive result will be enough for an early exit.
let mut ssa = false;
Each combination size:
for n in 1 ..= mx {
Each combination:
for c in a.iter().combinations(n) {
Get the sum of the included elements.
let ca = c.iter().map(|i| *i).sum::<i32>();
If the mean of that equals the mean of everything else, return true
.
if (ca as f64) / (n as f64) == ((ss - ca) as f64) / ((ml - n) as f64) {
ssa = true;
break;
}
}
if ssa {
break;
}
}
ssa
}
Full code on
github.
Comments on this post are now closed. If you have particular grounds for adding a late comment, comment on a more recent post quoting the URL of this one.