I’ve been doing the Weekly
Challenges. The
latest
involved word hunting and integer combinations. (Note that this ends
today.)
Fewer langauges this time, though, as I was on holiday.
Task 1: Count Common
You are given two array of strings, @words1
and @words2
.
Write a script to return the count of words that appears in both arrays exactly once.
Rust's Counter
class does most of the work for me, definining a
union as the larger value and an intersection as both-values-present.
fn countcommon(a: Vec<&str>, b: Vec<&str>) -> usize {
let ac = a.into_iter().collect::<Counter<_>>();
let bc = b.into_iter().collect::<Counter<_>>();
let ch = ac.clone() | bc.clone();
let cl = ac & bc;
cl.keys().filter(|k| *ch.get(*k).unwrap() == 1).count()
}
PostScript is a bit more work, setting up the counted hashes:
/countcommon {
0 dict begin
/bc 0 dict def
{
/w exch def
bc w bc w 0 dget 1 add put
} forall
/ac 0 dict def
{
/w exch def
ac w ac w 0 dget 1 add put
} forall
Then checking each word in ac
for presence excatly once in each sequence.
ac keys {
/k exch def
ac k get 1 eq
bc k 0 dget 1 eq
and
} filter length
end
} bind def
Task 2: Strong Pair
You are given an array of integers, @ints
.
Write a script to return the count of all strong pairs in the given array.
A pair of integers x and y is called strong pair if it satisfies: 0
< |x - y| < min(x, y).
So it's basically combinatorics again, and we have code for that.
Perl:
#! /usr/bin/perl
sub strongpair($a0) {
my @a = sort {$a <=> $b} keys %{{map {$_ => 1} @{$a0}}};
my $count = 0;
my $ip = combinations(\@a, 2);
while (my $c = $ip->next) {
if (abs($c->[0] - $c->[1]) < min(@{$c})) {
$count++;
}
}
return $count;
}
Full code on
github.