# RabbitFarm

### 2023-07-23

#### Shuffled Operations

*The examples used here are from the weekly challenge problem statement and demonstrate
the working solution.*

## Part 1

*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.*

### Solution

```
use v5.38;
sub shuffle_string{
my($s, $indices) = @_;
my @s = split(//, $s);
my @t;
do { $t[$_] = shift @s } for @{$indices};
return join(q//, @t);
}
MAIN:{
say shuffle_string(q/lacelengh/, [3, 2, 0, 5, 4, 8, 6, 7, 1]);
say shuffle_string(q/rulepark/, [4, 7, 3, 1, 0, 5, 2, 6]);
}
```

### Sample Run

```
$ perl perl/ch-1.pl
challenge
perlraku
```

### Notes

I had to think of this one a bit! What we need to do is take each letter, from left to
right, and assign it a new position. It's not often you see a `shift`

within another loop
but here that is the key to getting everything working.

## Part 2

*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.*

### Solution

```
use v5.38;
sub zero_array{
my $operations = 0;
do{
return $operations if 0 == unpack(q/%32I*/, pack(q/I*/, @_));
my $minimum = (sort { $a <=> $b } grep { $_ > 0 } @_)[0];
@_ = map { $_ > 0 ? $_ - $minimum : 0 } @_;
$operations++;
} for @_;
}
MAIN:{
say zero_array 1, 5, 0, 3, 5;
say zero_array 0;
say zero_array 2, 1, 4, 0, 3
}
```

### Sample Run

```
$ perl perl/ch-2.pl
3
0
4
```

### Notes

Usually I assign function arguments new names, even if I am just passing in a single array
of values like in this example. I decided this time to not do it, I don't think
readability is sacrificed. Provided the reader actually knows what `@_`

is I think for a
short function such as this it's fine. In fact, I think an argument could be made that
readability is actually enhanced since lines such as the one with both a `sort`

and a
`grep`

are kept to a shorter length.

## References

posted at: 20:55 by: Adam Russell | path: /perl | permanent link to this entry

The Weekly Challenge 226 (Prolog Solutions)

*The examples used here are from the weekly challenge problem statement and demonstrate
the working solution.*

## Part 1

*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.*

### Solution

```
letter_shuffle(Shuffled, Letter, Index):-
nth(Index, Shuffled, Letter).
```

### Sample Run

```
$ gprolog --consult-file prolog/ch-1.p
| ?- length(L, 9), maplist(letter_shuffle(L), "lacelengh", [4, 3, 1, 6, 5, 9, 7, 8, 2]), atom_codes(A, L).
A = challenge
L = [99,104,97,108,108,101,110,103,101]
yes
```

### Notes

Many Prologs, including GNU Prolog, treat double quoted strings as lists of the character
codes representing each letter. So here `maplist/3`

is presented such a list as well as
the given list of indices. We give a `letter_shuffle/3`

an empty list of the right length
and all that is left is for `nth/3`

to assign the letters as needed.

## Part 2

*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.*

### Solution

```
subtract_minimum(Minimum, X, Y):-
Y is X - Minimum.
zero_array(Numbers, Operations):-
delete(Numbers, 0, NumbersNoZero),
zero_array(NumbersNoZero, 0, Operations).
zero_array([], Operations, Operations).
zero_array(Numbers, OperationsCounter, Operations):-
delete(Numbers, 0, NumbersNoZero),
min_list(NumbersNoZero, Minimum),
maplist(subtract_minimum(Minimum), NumbersNoZero, NumbersSubtracted),
succ(OperationsCounter, OperationsCounterNext),
delete(NumbersSubtracted, 0, NumbersSubtractedNoZero),
zero_array(NumbersSubtractedNoZero, OperationsCounterNext, Operations).
```

### Sample Run

```
$ gprolog --consult-file prolog/ch-2.p
| ?- zero_array([1, 5, 0, 3, 5], Operations).
Operations = 3 ?
yes
| ?- zero_array([0], Operations).
Operations = 0 ?
yes
| ?- zero_array([2, 1, 4, 0, 3], Operations).
Operations = 4 ?
yes
| ?-
```

### Notes

A convenient issue with this problem is that once a list entry is zero we can ignore it.
Since we can ignore it we can `delete/3`

it and thereby reduce the list eventually to the
empty list, the base of our recursion. Each time we recurse we find the minimum element,
subtract it from all others, and increment the number of operations.

## References

posted at: 16:52 by: Adam Russell | path: /prolog | permanent link to this entry