Yeah, yeah, it feels like a bit of a stretch this week, but when I saw the tasks, my brain read off “Largest of Three” to the tune of “Power of Two” by The Indigo Girls. No more of a stretch than Three of a Reverse Sum Pair was, I guess.
Task 1: Sort Language
You are given two array of languages and its popularity.
Write a script to sort the language based on popularity.
Example 1
Input: @lang = ('perl', 'c', 'python')
@popularity = (2, 1, 3)
Output: ('c', 'perl', 'python')
Example 2
Input: @lang = ('c++', 'haskell', 'java')
@popularity = (1, 3, 2)
Output: ('c++', 'java', 'haskell')
Approach
This could be done with a single loop, using the second array to assign values from the first array to particular indices in the output array:
for (i = 0; i < length(lang); i++) {
output[ popularity[i]-1 ] = lang[i];
}
But this task is phrased as a sort, so let’s code it that way: the second array has the values we’ll use to compare the first array elements with in a custom sort.
Raku
sub sortLanguage(@lang, @popularity) {
# build a hash associating @popularity with @lang
my %lang_pop = map {
@lang[$_] => @popularity[$_]
}, @lang.keys;
my @sorted = @lang.sort({
# sort by %lang_pop, not @lang
%lang_pop{$^a} <=> %lang_pop{$^b}
});
return @sorted;
}
I’m remembering my discovery last week that @lang.keys
would give me the sequence 0, 1, 2
.
View the entire Raku script for this task on GitHub.
Perl
Again, the changes from Raku to Perl aren’t Earth-shattering:
sub sortLanguage{
my ($lang, $popularity) = @_;
# build a hash associating @popularity with @lang
my %lang_pop = map {
$lang->[$_] => $popularity->[$_]
} 0 .. $#{$lang};
my @sorted = sort {
# sort by %lang_pop, not @$lang
$lang_pop{$a} <=> $lang_pop{$b}
} @$lang;
return @sorted;
}
View the entire Perl script for this task on GitHub.
Python
Python’s nifty sorted
built-in makes this pretty easy.
def sortLanguage(lang, popularity):
# build a dict associating popularity with lang
lang_pop = {
v: popularity[i] for i,v in enumerate(lang)
}
sorted_list = sorted(lang,
# sort by lang_pop, not lang
key=lambda x: (lang_pop[x]))
return sorted_list
View the entire Python script for this task on GitHub.
Task 2: Largest of Three
You are given an array of integers >= 0.
Write a script to return the largest number formed by concatenating some of the given integers in any order which is also multiple of 3. Return -1 if none found.
Example 1
Input: @ints = (8, 1, 9)
Output: 981
981 % 3 == 0
Example 2
Input: @ints = (8, 6, 7, 1, 0)
Output: 8760
Example 3
Input: @ints = (1)
Output: -1
Approach
Ok, it’s pretty obvious that the largest combination will have the digits sorted in descending order, so I’m guessing I want to sort the digits first, and then start making combinations until I either a) find a combination that’s a multiple of 3, or b) exhaust my combinations.
Raku
sub largestOfThree(@ints) {
my $max = -1; # initialize our failure case
for @ints.combinations -> @combo {
next unless @combo.elems > 0; # not empty set
# sort the digits in descending order,
# join them, then convert to an Int
my $num = @combo.sort.reverse.join('').Int;
next unless $num > $max; # not bigger than current max
next unless $num % 3 == 0; # not divisible by 3
$max = $num;
}
return $max;
}
View the entire Raku script for this task on GitHub.
Perl
Again, Algorithm::Combinatorics’ combinations
function comes to the rescue.
use Algorithm::Combinatorics qw( combinations );
sub largestOfThree {
my @ints = @_;
my $max = -1; # initialize our failure case
my @combos = map {
combinations(\@ints, $_)
} 1 .. scalar(@ints);
foreach my $combo ( @combos ) {
# sort the digits in descending order,
# join them, then convert to an Int
my $num = join('', reverse sort @$combo) + 0;
next unless $num > $max; # not bigger than current max
next unless $num % 3 == 0; # not divisible by 3
$max = $num;
}
return $max;
}
View the entire Perl script for this task on GitHub.
Python
from itertools import combinations
def largestOfThree(ints):
# generate a list of combinations
combos = [
c for i in range(1, len(ints)+1)
for c in combinations(ints, i)
]
maxval = -1 # initialize our failure case
for combo in combos:
combo_list = list(combo)
combo_list.sort(reverse=True)
num = int(''.join(map(str, combo_list)))
if num <= maxval: # not bigger than current max
continue
if num % 3 != 0: # not divisible by 3
continue
maxval = num
return maxval
At least this week I made the nested for loops to generate the combinations prettier.
View the entire Python script for this task on GitHub.
Here’s all my solutions in GItHub: https://github.com/packy/perlweeklychallenge-club/tree/master/challenge-245/packy-anderson