# RogerBW's Blog

The Weekly Challenge 265: The Appearance of Completion 21 April 2024

I’ve been doing the Weekly Challenges. The latest involved hunting integers and filtering words. (Note that this ends today.)

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

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.