### Perl Weekly Challenge: Week 260

#### Challenge 1:

**Unique Occurrences**

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
```

In my Raku solution, the first thing I did was create a hash to store how many times each value was seen.

```
my %count;
```

Then I did the actual counting.

```
@ints.map({ %count{$_}++ });
```

If the total number of values seen is equal to the unique number of values seen, we print 1 otherwise we print 0.

```
say %count.values.elems == %count.values.unique.elems ?? 1 !! 0;
```

For the Perl version I once again had to reach into my archive of previous challenges; this time to find a replacement for
`.unique()`

. With that, it looks pretty similar to the Raku version.

```
my %count;
map { $count{$_}++ } @ints;
say scalar values %count == scalar unique([values %count]) ? 1 : 0;
```

#### Challenge 2:

**Dictionary Rank**

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
```

Raku can solve this in one slightly long line.

```
say %(@*ARGS[0].comb.permutations.map({$_.join}).sort.unique.kv.reverse){@*ARGS[0]} + 1
```

Starting from somewhere near the beginning, we get the word from the command line and split it into a list of characters with
`.comb()`

. Then we find all the permutations of that list with `.permutations()`

. We want strings not list so we join all those
permutation lists back with `.map()`

and `.join()`

. These strings are then sorted into dictionary order with `.sort()`

and duplicates are filtered out with `.unique()`

. At this point, we have a list of strings. `.kv()`

converts a list or array into key-value pairs where the value is an element of the list and the key is the index of the element in the list. `.Hash`

casts this list of pairs into a hash. But this hash is backwards for our purposes; we want to be able to look up the index based on the word not the other way around so we call `.reverse()`

which makes keys values and values keys. I wrapped up this whole statement in `%( ... )`

. This treats the key-value list as a hash. Now we can use the standard hash `{}`

syntax to look up the index of the word. One more slight problem though; array indexing starts from 0 but according to the spec, the rank should be 1-based. So we
have to add 1 to get the final answer.

For perl we need a `unique()`

replacement as in Challenge 1 and the `permute()`

function I have used in previous challenges.

```
my @permutations;
permute { push @permutations, \@_; } (split //, $word);
```

I need an explicit hash to store the dictionary ranks.

```
my %rank;
```

And then I can populate the hash with my permuted strings. The keys are the strings themselves, and the values are their index in the list of permutations.

```
my $index = 1;
for my $perm (sort (unique([map { join q{}, @{$_} } @permutations]))) {
$rank{$perm} = $index++;
}
```

Finally, I can look up the rank of the word and print it.

```
say $rank{$word};
```