with Raku

This is my response to The Weekly Challenge #260.

You are given an array of integers,

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:

File: unique-occurences-bag
`@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

#! /usr/bin/env raku
unit sub MAIN (*@ints where all(@ints) ~~ Int && @ints.elems > 0, # [1]
:v(:$verbose));
my @freq = @ints.Bag.values; # [2]
say ": Frequencies: @freq[]" if $verbose;
say @freq.repeated ?? 0 !! 1; # [3]

[1] All the arguments, of which there must be at least one, must be integers.

[2]
Turn the array into a `Bag`

, a hash like structure where
the original data are the keys and the original frequency are the values.
Then we use `values`

to get a list of frequencies.

See docs.raku.org/routine/Bag for more information about `Bag`

.

See docs.raku.org/routine/values for more information about `values`

.

[3] `repeated`

will give us a list of values that occur
more than once. Thus we print 1 if all the occurrences are unique and 0
otherwise.

See docs.raku.org/routine/repeated for more information about `repeated`

.

Running it:

$ ./unique-occurences 1 2 2 1 1 3
1
$ ./unique-occurences 1 2 3
0
$ ./unique-occurences -- -2 0 1 -2 1 1 0 1 -2 9
1

The `--`

is there to halt the parsing of command line options,
as `-2`

will be treated as an option otherwise.

Looking good.

With verbose mode:

$ ./unique-occurences -v 1 2 2 1 1 3
: Frequencies: 1 3 2
1
$ ./unique-occurences -v 1 2 3
: Frequencies: 1 1 1
0
$ ./unique-occurences -v -- -2 0 1 -2 1 1 0 1 -2 9
: Frequencies: 4 3 2 1
1

You are given a word,

Write a script to compute the dictionary rank of the given word.

Example 1:

File: dictionary-rank
`$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

#! /usr/bin/env raku
unit sub MAIN ($word where $word.chars > 0, :v(:$verbose)); # [1]
my $perm = $word.comb.sort.permutations>>.join.unique; # [2]
say ": Permutations: $perm[]" if $verbose;
my $index = ($perm.grep: $word, :k).first; # [3]
say $index +1; # [4]

[1] Ensure at least one character in the word.

[2] Using `permutations`

on an array of characters
gives us all the ways we can combine them. If we sort the characters, then
the output will also be sorted. The result so far is an array of arrays.
We apply `>>.join`

the inner arrays, so that we end ut with words. The
`unique`

will get rid of duplicates, which we get if we have repeated
letters in the input string.

[3] Look for the given word in the array of permutations, using
`grep`

. Adding the `:k`

(keys) adverb gives us the keys instead of
the values themselves, and the key in an array context is the index. This
is an array, with one element, so we use `first`

to get it.

See docs.raku.org/routine/first for more information about `first`

.

[4] The rank starts with 1 as the first one, so we add 1 to the zero based index.

Running it:

$ ./dictionary-rank CAT
3
$ ./dictionary-rank GOOGLE
88
$ ./dictionary-rank SECRET
255

Looking good.

With verbose mode:

./dictionary-rank -v CAT
: Permutations: ACT ATC CAT CTA TAC TCA
3
$ ./dictionary-rank -v GOOGLE
: Permutations: EGGLOO EGGOLO EGGOOL EGLGOO ... OOGLGE OOLEGG OOLGEG OOLGGE
88
$ ./dictionary-rank -v SECRET
: Permutations: CEERST CEERTS CEESRT CEESTR ... TSEREC TSRCEE TSRECE TSREEC

I have abbreviated the verbose output for the second and third example.

And that's it.