PWC 220
PWC 220
I switched to Raku this week. Both challenges are easier to tackle with Raku.
Challenge 1 (Common characters)
We are given a list of words, and asked to return a sorted list of the characters that are found in every word in the list (ignoring case). Here is the subroutine:
[(&)] @words.map( {$_.lc.comb.Set} )
}
For each word in @words, lowercase it, then split into characters, then store each unique character in a set. Then working on the resulting list of sets, call the reduce meta-operator [..] on the set intersection "(&)" operator, i.e., call [(&)] or "reduce using intersection" on the list of sets, to get the intersection of every set, or the characters that are found in every set. This returns a set, whose say method automatically prints the elements in sorted order (one of the task specifications).
Challenge 2 (Squareful)
We are given a list of integers @ints say. We are asked to identify every permutation of the list where every pair of adjacent elements adds up to a perfect square.
One could use an easy-to-code brute force approach where we check the condition for every possible permutation, though this is O(N!) and does not scale well. Somewhat more difficult is an O(N^2) approach that finds every pair of elements in @ints that adds up to a perfect square, and then uses this to construct the required permutations.
I use the easy approach since all the test examples have just 3 elements, though I explicitly restrict my Raku subroutine to lists with three elements, to signal that the approach will not scale up. Here is my squareful subroutine with a couple of helper subroutines:
($a+$b).sqrt %% 1;
}
multi sub is_perfect_square( @ints ) {
( [&&] (0 .. @ints-2).map( {&is_perfect_square( @ints[$_], @ints[$_+1] ) } ) );
}
sub squareful (@ints where @ints.elems==3) {
@ints.permutations.unique( :with(&[eqv]) ).grep( {$_.&is_perfect_square} );
}
The subroutine &is_perfect_square taking two integer arguments checks if their sum is a perfect square. The subroutine &is_perfect_square taking an array as argument checks if every pair of adjacent elements adds up to a perfect square (by calling &is_perfect_square on each pair of adjacent elements). Finally, the subroutine &squareful calls &is_perfect_square on every permutation of @ints, and returns a list of those permutations that return True. This list can potentially contain duplicates, since the Raku permutations operator treats identical elements of a list as if they are different elements, so that for example, (2,2,2).permutations returns six (identical) permutations rather than just a single permutation. So we call unique to eliminate duplicates.
Comments