I’ve been doing the Weekly
Challenges. The
latest
involved hunting integers and filtering words. (Note that this ends
today.)
Task 1: 33% Appearance
You are given an array of integers, @ints
.
Write a script to find an integer in the given array that appeared
33% or more. If more than one found, return the smallest. If none
found then return undef
.
So I'll count the occurrences, and compare with a threshold value.
Python:
def thirtythreepercentappearance(a):
Count occurrences.
m = defaultdict(lambda: 0);
for n in a:
m[n] += 1
Work out the threshold.
threshold = floor(len(a) * 33 / 100)
If it wasn't an exact integer value, nudge it up by 1. (So 100 yields
a threshold off 33, but 4 yields 2.)
if floor(threshold * 100 / 33) != len(a):
threshold += 1
Get the list of qualifying keys.
s = [k for k in m.keys() if m[k] >= threshold]
And return either the minimum of them, or a flag value. (In Rust I can
use an Option.)
if len(s) > 0:
return min(s)
else:
return -1
Task 2: Completing Word
You are given a string, $str
containing alphnumeric characters and
array of strings (alphabetic characters only), @str
.
Write a script to find the shortest completing word. If none found
return empty string.
A completing word is a word that contains all the letters in the
given string, ignoring space and number. If a letter appeared more
than once in the given string then it must appear the same number or
more in the word.
Once more it's the hash as count of occurrences, this time also
filtering for relevant characters. Perl:
Build a hash from a string.
sub str2hash($a) {
my %m;
foreach my $c (split '', $a) {
if ($c =~ /[[:alpha:]]/) {
$m{lc($c)}++;
}
}
return \%m;
}
sub completingword($a, $cw) {
Make the reference hash.
my $ah = str2hash($a);
my @out;
For each possible completing word, make its hash.
foreach my $t (@{$cw}) {
my $valid = 1;
my $th = str2hash($t);
Fiddly bit to reset the hash access counter, since we'll be using
each
multiple times on the same hash.
keys %{$ah};
while (my ($k, $v) = each %{$ah}) {
If the cw hash doesn't have an entry that's in the main word hash,
unless (exists $th->{$k}) {
$valid = 0;
last;
}
or it doesn't have enough letters, bail out.
if ($th->{$k} < $v) {
$valid = 0;
last;
}
}
Otherwise this is a valid completing word.
if ($valid) {
push @out, $t;
}
}
No completions? Return empty string.
unless (@out) {
return "";
}
Otherwise return the shortest.
return (sort {length($::a) <=> length($::b)} @out)[0];
}
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.