Robbie Hatley's Solutions To The Weekly Challenge #260
For those not familiar with "The Weekly Challenge", it is a weekly programming puzzle with two parts, cycling every Sunday. You can find it here:
This week (2024-03-10 through 2024-03-16) is weekly challenge #260. Its tasks are as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Task 260-1: Unique Occurrences Submitted by: Mohammad Sajid Anwar You are given an array of integers, @ints. Write a script to return 1 if the number of occurrences of each value in the given array is unique or 0 otherwise. Example 1: Input: @ints = (1,2,2,1,1,3) Output: 1 The number 1 occurred 3 times. The number 2 occurred 2 times. The number 3 occurred 1 time. All occurrences are unique, therefore the output is 1. Example 2 Input: @ints = (1,2,3) Output: 0 Example 3 Input: @ints = (-2,0,1,-2,1,1,0,1,-2,9) Output: 1
There are probably other ways to solve this (TIMTOWTDI), but the method I stumbled on was to first create a sub called "occurrences" which returns a list of the occurrences of the various kinds of elements in the input array, then I apply "occurrences" twice, basically "occurrences of occurrences". If the result is a list of 1s, then the occurrences of element kinds are unique, otherwise they aren't. Instead of checking every element of "occurrences of occurrences" individually, I just look at their product; if it's 1, the occurrences are unique, otherwise they aren't:
use v5.38; use utf8; use List::Util 'product'; # What are the occurrences of the elements of an array? sub occurrences(@array) { my %a; for my $item (@array) {++$a{$item};} return values %a; } # Are the occurrences of the elements of an array unique? sub occurrences_are_unique(@array) { return 1 == product occurrences occurrences @array; } my @arrays = @ARGV ? eval($ARGV[0]) : ( [1,2,2,1,1,3], [1,2,3], [-2,0,1,-2,1,1,0,1,-2,9], ); for my $aref (@arrays) { say ''; say '@ints = (', join(', ', @$aref), ')'; occurrences_are_unique @$aref and say 1, ' (occurrences are unique)' or say 0, ' (occurrences are not unique)'; }
Robbie Hatley's Perl Solution to The Weekly Challenge 260-1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Task 260-2: Dictionary Rank Submitted by: Mark Anderson You are given a word, $word. Write a script to compute the dictionary rank of the given word. Example 1: Input: $word = 'CAT' Output: 3 All possible combinations of the letters: CAT, CTA, ATC, TCA, ACT, TAC Arrange them in alphabetical order: ACT, ATC, CAT, CTA, TAC, TCA CAT is the 3rd in the list. Therefore the dictionary rank of CAT is 3. Example 2: Input: $word = 'GOOGLE' Output: 88 Example 3: Input: $word = 'SECRET' Output: 255
Example 1 says "combinations", but the context makes it clear that the author actually meant "permutations". With that in mind, I use the "permute" function from CPAN module "Math::Combinatorics" to get a list of all letter orders, then sort, then use the "uniq" function from CPAN module "List::Util" to get rid of duplicates, then use the "firstidx" function from CPAN module "List::MoreUtils" to find the index of the first element which is equal to the original word, then add 1 for 1-indexing:
use v5.38; use utf8; use Math::Combinatorics 'permute'; use List::Util 'uniq'; use List::MoreUtils 'firstidx'; # What is the "dictionary order" (as defined in the problem # description) of a word? sub dictionary_order ($word) { my @dic = uniq sort map {join '', @$_} permute split //, $word; return 1 + firstidx {$_ eq $word} @dic; } my @words = @ARGV ? @ARGV : qw( CAT GOOGLE SECRET ); for my $word (@words) { say ''; say "word = $word"; say 'dictionary order = ', dictionary_order($word); }
Robbie Hatley's Perl Solution to The Weekly Challenge 260-2
That's it for challenge 260; see you on challenge 261!
Comments
Post a Comment