## Weekly Challenge 284

Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.

## Task 1: Lucky Integer

### Task

You are given an array of integers, `@ints`

.

Write a script to find the lucky integer if found otherwise return `-1`

. If there are more than one then return the largest.

A lucky integer is an integer that has a frequency in the array equal to its value.

### My solution

This task is relatively straight forward, so doesn't require much explanation. I create a dict (hash in Perl) of the frequency of each integer, called `freq`

. I then iterate through the keys of `freq`

(highest value first). If the frequency of the integer is the same as the value, I return that number. If the iterator is exhausted, I return `-1`

.

```
def lucky_integer(ints: list) -> str:
freq = Counter(ints)
for i in sorted(freq, reverse=True):
if i == freq[i]:
return i
return -1
```

### Examples

```
$ ./ch-1.py 2 2 3 4
2
$ ./ch-1.py 1 2 2 3 3 3
3
$ ./ch-1.py 1 1 1 3
-1
```

## Task 2: Relative Sort

### Task

You are given two list of integers, `@list1`

and `@list2`

. The elements in the `@list2`

are distinct and also in the `@list1`

.

Write a script to sort the elements in the `@list1`

such that the relative order of items in `@list1`

is same as in the `@list2`

. Elements that is missing in `@list2`

should be placed at the end of `@list1`

in ascending order.

### My solution

While Python does have the `index`

function for lists, it will raise a `ValueError`

exception if the item is not in the list. Therefore I have created a function called `find_index`

that will return the position of `val`

in `lst`

if found, or return the length of the list if not.

```
def find_index(lst: list, val: int):
return lst.index(val) if val in lst else len(lst)
```

The Perl solution also has the same function, and uses List::MoreUtil's first_index to find the position.

```
sub find_index( $lst, $val ) {
my $idx = first_index { $_ == $val } @$lst;
return $idx == -1 ? scalar(@$lst) : $idx;
}
```

I use the sorted function to sort the first list. Each item is sorted by a tuple of the index position and the integer. This ensures that the first part of the resulting list are sorted in accordance with the position in the second list, while the remaining values are sorted numerically.

```
def relative_sort(list1: list, list2: list) -> list:
return sorted(list1, key=lambda i: (find_index(list2, i), i))
```

The Perl solution uses the same logic, but completely different syntax.

```
sub main ($lists) {
my $list1 = $lists->[0];
my $list2 = $lists->[1];
my @solution = sort {
find_index( $list2, $a ) <=> find_index( $list2, $b )
or $a <=> $b
} @$list1;
say '(', join( ', ', @solution ), ')';
}
```

For input via the command line, I take a JSON string that should be a list of list of integers.

### Examples

```
$ ./ch-2.py "[[2, 3, 9, 3, 1, 4, 6, 7, 2, 8, 5],[2, 1, 4, 3, 5, 6]]"
(2, 2, 1, 4, 3, 3, 5, 6, 7, 8, 9)
$ ./ch-2.py "[[3, 3, 4, 6, 2, 4, 2, 1, 3],[1, 3, 2]]"
(1, 3, 3, 3, 2, 2, 4, 4, 6)
$ ./ch-2.py "[[3, 0, 5, 0, 2, 1, 4, 1, 1],[1, 0, 3, 2]]"
(1, 1, 1, 0, 0, 3, 2, 4, 5)
```

## Top comments (0)