Perl Weekly Challenge 260.

My solutions (task 1 and task 2 ) to the The Weekly Challenge - 260.

Task 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

I can use a hash to keep track of how many times a value appears. Then I consider the values of that hash and test their unicity.

perl -MList::Util=uniq -E '
++$x{$_} for @ARGV; @y=values %x; say "@ARGV => ", (@y==uniq @y)||0;
' 1 2 2 1 1 3

Results:

1 2 2 1 1 3 => 1

perl -MList::Util=uniq -E '
++$x{$_} for @ARGV; @y=values %x; say "@ARGV => ", (@y==uniq @y)||0;
' 1 2 3

Results:

1 2 3 => 0

perl -MList::Util=uniq -E '
++$x{$_} for @ARGV; @y=values %x; say "@ARGV => ", (@y==uniq @y)||0;
' -- -2 0 1 -2 1 1 0 1 -2 9

Results:

-2 0 1 -2 1 1 0 1 -2 9 => 1

The full code follows:

 1  # Perl weekly challenge 260
 2  # Task 1:  Unique Occurrences
 3  #
 4  # See https://wlmb.github.io/2024/03/10/PWC260/#task-1-unique-occurrences
 5  use v5.36;
 6  use List::Util qw(uniq);
 7  die <<~"FIN" unless @ARGV;
 8      Usage: $0 N1 [N2...]
 9      to test if the number of ocurrences of each number is unique.
10      FIN
11  my %counts;
12  ++$counts{$_} for @ARGV;
13  my @counts=values %counts;
14  my $result=@counts==(uniq @counts)||0;
15  say "@ARGV => $result";

Examples:

./ch-1.pl 1 2 2 1 1 3
./ch-1.pl 1 2 3
./ch-1.pl -2 0 1 -2 1 1 0 1 -2 9

Results:

1 2 2 1 1 3 => 1
1 2 3 => 0
-2 0 1 -2 1 1 0 1 -2 9 => 1

Task 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

I split the word into characters, perform all permutations with permutations from Algorithm::Combinatorics, assemble them into words, keep unique words with uniq sort them and find the index of the given word with onlyidx from List::AllUtils. This fits a 1.5liner.

perl -MAlgorithm::Combinatorics=permutations -MList::AllUtils=uniq,onlyidx -E '
for(@ARGV){@x=split "", $x=lc; say "$_ => ", 1+onlyidx{$_ eq $x} sort{$a cmp $b}
uniq map {join "", @$_} permutations(\@x);}
' CAT GOOGLE SECRET

Results:

CAT => 3
GOOGLE => 88
SECRET => 255

The full code follows:

 1  # Perl weekly challenge 260
 2  # Task 2:  Dictionary Rank
 3  #
 4  # See https://wlmb.github.io/2024/03/10/PWC260/#task-2-dictionary-rank
 5  use v5.36;
 6  use Algorithm::Combinatorics qw(permutations);
 7  use List::AllUtils qw(uniq onlyidx);
 8  die <<~"FIN" unless @ARGV;
 9      Usage: $0 W1 [W2...]
10      to find the dictionary rank of words W1 W2...
11      FIN
12  for(@ARGV){
13      my @letters=split "", my $word=lc;
14      say "$_ => ", 1+onlyidx {$_ eq $word}
15           sort{$a cmp $b}
16           uniq
17  	 map {join "", @$_}
18           permutations(\@letters);
19  }

Example:

./ch-2.pl CAT GOOGLE SECRET

Results:

CAT => 3
GOOGLE => 88
SECRET => 255

/;

Written on March 10, 2024