# Shuffle Off To Buffalo: Weekly Challenge #226

We’re on to Challenge #226. **226** is a semiprime, in that it is *2 x 113*. It is also a Happy. I suppose that makes most numbers unhappy?

### Task 1: Shuffle String

Submitted by: Mohammad S Anwar

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.

#### Talking It Through

It says *shuffle*, but we don’t do any shuffling here. Really, it’s kinda unshuffling. We’re given a word and a series of positions where those letters should be.

My solution is to create a string of spaces the same length as the input string, then use the fact that `substr`

can be an lvalue as well, meaning you can write both `$x = substr $string, 1,1`

and `substr( $string, 1,1) = $x`

. `l`

is the first character in the $input, with the position of `3`

, so `substr( $output,3,1) = substr( $input, 0,1)`

. The third value is the length of the substring, of course, and one loop gets us through the whole thing.

#### Show Me The Code

```
#!/usr/bin/env perl
use strict;
use warnings;
use experimental qw{ say postderef signatures state };
my @examples = (
[ 'lacelengh', [ 3, 2, 0, 5, 4, 8, 6, 7, 1 ] ],
[ 'rulepark', [ 4, 7, 3, 1, 0, 5, 2, 6 ] ]
);
for my $example (@examples) {
my $string = $example->[0];
my $indices = join ',', $example->[1]->@*;
my $output = reorder_string( $example->[0], $example->[1] );
say <<~"END";
Input: \$string = '$string', \@indices = ($indices)
Output: '$output'
END
}
sub reorder_string ( $input, $indices ) {
my $output = ' ' x length $input;
my $c = 0;
for my $i ( $indices->@* ) {
substr( $output, $i, 1 ) = substr( $input, $c, 1 );
$c++;
}
return $output;
}
```

```
$ ./ch-1.pl
Input: $string = 'lacelengh', @indices = (3,2,0,5,4,8,6,7,1)
Output: 'challenge'
Input: $string = 'rulepark', @indices = (4,7,3,1,0,5,2,6)
Output: 'perlraku'
```

### Task 2: Zero Array

Submitted by: Mohammad S Anwar 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.

#### Talking It Through

You have an array.

- find the smallest non-zero value in the array
- subtract that from every value that isn’t zero
- all zeroes stay zeroes
- stop when everything is zeroes

That’s simple, and the code within the while loop is fairly simple. I might trade the ternary operator for two maps (`map { $_>0?$_:0} map { $_ -= $min }`

) but am happy with my one-map solution.

What annoys me is that I couldn’t get my tests to end the while loop all failed, leaving me with `while (1) { ... ; last if $min == 0}`

. Testing on `max @ints`

should work but didn’t, and neither did `sum @ints`

.

#### Show Me The Code

```
#!/usr/bin/env perl
use strict;
use warnings;
use experimental qw{ say postderef signatures state };
use List::Util qw{ sum sum0 min max };
my @examples = ( [ 1, 5, 0, 3, 5 ], [0], [ 2, 1, 4, 0, 3 ], );
for my $e (@examples) {
my $input = join ',', $e->@*;
my $output = zero_array( $e->@* );
say <<~"END";
Input: \@ints = ($input)
Output: $output
END
}
sub zero_array( @ints ) {
my $c = -1;
while (1) {
$c++;
my $min = min grep { $_ > 0 } @ints;
$min //= 0;
@ints = map { $_ - $min > 0 ? $_ - $min : 0 } @ints;
last if $min == 0;
last if $c > 10;
}
return $c;
}
```

```
$ ./ch-2.pl
Input: @ints = (1,5,0,3,5)
Output: 3
Input: @ints = (0)
Output: 0
Input: @ints = (2,1,4,0,3)
Output: 4
```