Weekly Challenge 398
Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. Unless otherwise stated, Copilot (and other AI tools) have NOT been used to generate the solution. It's a great way for us all to practice some coding.
Task 1: Divisible Average
You are given an array of positive integers.
Write a script to return the closest integer to the mean value of all even integers that are divisible by 3. If none is divisible, return 0.
My solution
An even number that is divisible by 3, means it must be divisible by 6. I create a list (array in Perl) called eligible_ints which has all integers that match this critera.
If the list is empty (i.e. there are no integers divisble by 6), I return 0. Otherwise I return the nearest integer. Python's round function uses "bankers rounding" when half values round to the nearest even number.
def divisible_average(ints: list[int]) -> int:
eligible_ints = [i for i in ints if i % 6 == 0]
if not eligible_ints:
return 0
return round(sum(eligible_ints) / len(eligible_ints))
The Perl solution uses the same logic. This round half values upwards.
sub main (@ints) {
my @eligible_ints = grep { $_ % 6 == 0 } @ints;
if ( scalar(@eligible_ints) ) {
say sprintf "%.0f", sum(@eligible_ints) / scalar(@eligible_ints);
}
else {
say 0;
}
}
Examples
$ ./ch-1.py 18 5 7 11
18
$ ./ch-1.py 6 12 18 24 30 40
18
$ ./ch-1.py 3 9 15 21 27
0
$ ./ch-1.py 6 12 14 20
9
$ ./ch-1.py 6 6 6 12 12
8
Task 2: String Difference
You are given an array of equal length strings.
Write a script to find the difference integer array of each word in the given array. There will be one word with a different array; return that word.
Each words[i] can be converted into a difference integer array difference[i] of length n - 1 where difference[i][j] = words[i][j+1] - words[i][j]
My solution
I start this task by checking all words are of the same length.
from collections import defaultdict
def string_difference(words: list[str]) -> str:
if any(len(word) != len(words[0]) for word in words):
raise ValueError("Words must be of the same length")
I then create a dict called word_difference which starts by checking if the word is made up of lower case letters of the English alphabet. I then create a tuple of the differences in each letter. As a tuple is immutable, it can be used as a key in a dict. The defaultdict is a special dictionary that will auto-create the key if it does not exist.
word_difference = defaultdict(list)
for word in words:
if not re.search("^[a-z]+$", word):
raise ValueError(f"The word {word} is not all lower case English letters")
t = tuple(ord(word[i]) - ord(word[i - 1]) for i in range(1, len(word)))
word_difference[t].append(word)
I then find all words that have a unique key.
unique_words = [
word_list[0] for word_list in word_difference.values() if len(word_list) == 1
]
If there is only one word, I return it. If there are zero or two or more, I raise an exception.
if len(unique_words) == 1:
return unique_words[0]
raise ValueError(f"There were {len(unique_words)} words with unique differences")
The Perl solution follows a similar pattern. As Perl cannot use an array as a key to a hash, I join the @differences value with a space to generate the key.
use List::Util 'any';
sub main (@words) {
my %word_difference = ();
if ( any { length($_) != length( $words[0] ) } @words ) {
die "Words must be of the same length\n";
}
foreach my $word (@words) {
# Check words only contain lower case letters
if ( $word !~ /^[a-z]+$/ ) {
die "The word $word is not all lower case English letters\n";
}
my @differences = map {
ord( substr( $word, $_, 1 ) ) - ord( substr( $word, $_ - 1, 1 ) )
} ( 1 .. length($word) - 1 );
push @{ $word_difference{ join( " ", @differences ) } }, $word;
}
my @unique_words =
map { $_->[0] } grep { scalar(@$_) == 1 } values(%word_difference);
if ( scalar(@unique_words) == 1 ) {
say $unique_words[0];
}
else {
say "There were ", scalar(@unique_words),
" words with unique differences";
}
}
Examples
$ ./ch-2.py ab bc cd zy
zy
$ ./ch-2.py cba fed azy
azy
$ ./ch-2.py pop ada beb cfc
pop
$ ./ch-2.py aaaa zzzz mmmm aaba
aaba
$ ./ch-2.py aceg bdfh cegi azbz
azbz
Top comments (0)