### Perl Weekly Challenge: Week 226

#### Challenge 1:

**Shuffle String**

You are given a string and an array of indices of same length as string.

Write a script to return the string after re-arranging the indices in the correct order.

##### Example 1

```
Input: $string = 'lacelengh', @indices = (3,2,0,5,4,8,6,7,1)
Output: 'challenge'
```

##### Example 2

```
Input: $string = 'rulepark', @indices = (4,7,3,1,0,5,2,6)
Output: 'perlraku'
```

Alas, in a break with long-standing tradition, challenge 1 will not be solved with a one-liner this week. But this solution is also pretty straightforward.

First we split the `$string`

up into a list of individual letters.

```
my @letters = $string.comb;
```

We will also need a list to store the result.

```
my @result;
```

Using the `Z`

or zip operator, we form pairs of a letter from `@letters`

and the index in the equivalent
position in `@indices`

then place the letter at that index in `@result`

.

```
for @letters Z @indices -> ($letter, $index) {
@result[$index] = $letter;
}
```

Then all we need to do is join @results up into a string and print it.

```
@result.join.say;
```

The Perl version is similar.

```
my @letters = split //, $string;
my @result;
```

In the absence of `Z`

we just loop through the indexes of `@indices`

and use that to find the equivalent position in `@letters.`

So this won't work if `@letters`

and `@indices`

are of different length. That's not something we need to worry about for
the examples though.

```
for my $i (0 .. scalar @indices - 1) {
$result[$indices[$i]] = $letters[$i];
}
say join q{}, @result;
```

#### Challenge 2:

**Zero Array**

You are given an array of non-negative integers, @ints.

Write a script to return the minimum number of operations to make every element equal zero.

In each operation, you are required to pick a positive number less than or equal to the smallest element in the array, then subtract that from each positive element in the array.

##### Example 1

```
Input: @ints = (1, 5, 0, 3, 5)
Output: 3
operation 1: pick 1 => (0, 4, 0, 2, 4)
operation 2: pick 2 => (0, 2, 0, 0, 2)
operation 3: pick 2 => (0, 0, 0, 0, 0)
```

##### Example 2

```
Input: @ints = (0)
Output: 0
```

##### Example 3

```
Input: @ints = (2, 1, 4, 0, 3)
Output: 4
operation 1: pick 1 => (1, 0, 3, 0, 2)
operation 2: pick 1 => (0, 0, 2, 0, 1)
operation 3: pick 1 => (0, 0, 1, 0, 0)
operation 4: pick 1 => (0, 0, 0, 0, 0)
```

We start the Raku solution by assigning storage for a count of operations that might be performed.

```
my $ops = 0;
```

Then until all elements of `@ints`

equal 0...

```
until @ints.all == 0 {
```

...we find the smallest element of `@ints`

with `.min()`

after filtering out all the 0's with `.grep()`

so we don't
get 0 every time.

```
my $pick = @ints.grep({ $_ != 0 }).min;
```

Then we transform `@ints`

with `.map()`

so that each non-zero element is reduced by the value of `$pick`

.

```
@ints = @ints.map({ $_ == 0 ?? 0 !! $_ - $pick });
```

This is one operation as the spec calls it so we increment `$ops`

.

```
$ops++;
}
```

And finally we print out how many operations were performed.

```
say $ops;
```

The spec wasn't clear as to what should happen if one of the elements of `@ints`

becomes negative as a result of an operation.
This doesn't occur in any of the examples so I didn't think about it any further.

This is the Perl version.

```
my $ops = 0;
while (scalar grep {$_ != 0} @ints) {
```

I got around Perls' lack of `.min()`

by sorting the non-zero elements of `@ints`

and taking the first element which will be
the smallest.

```
my $pick = [sort { $a <=> $b } grep { $_ != 0 } @ints]->[0];
@ints = map { $_ == 0 ? 0 : $_ - $pick } @ints;
$ops++;
}
say $ops;
```