### Perl Weekly Challenge: Week 269

#### Challenge 1:

**Bitwise OR**

You are given an array of positive integers,

`@ints`

.Write a script to find out if it is possible to select two or more elements of the given array such that the bitwise OR of the selected elements has atlest one trailing zero in its binary representation.

##### Example 1

```
Input: @ints = (1, 2, 3, 4, 5)
Output: true
Say, we pick 2 and 4, their bitwise OR is 6. The binary representation of 6 is 110.
Return true since we have one trailing zero.
```

##### Example 2

```
Input: @ints = (2, 3, 8, 16)
Output: true
Say, we pick 2 and 8, thier bitwise OR is 10. The binary representation of 10 is 1010.
Return true since we have one trailing zero.
```

##### Example 3

```
Input: @ints = (1, 2, 5, 7, 9)
Output: false
```

Raku does it again and solves this task in one line.

```
say @*ARGS.combinations(2 .. @*ARGS.elems).grep({ ([+|] @$_).base(2).ends-with(0) }).elems > 0
```

We use the command-line arguments as input and then get all combinations of 2 or more elements with `.combinations()`

. Then using
`.grep()`

we go through each combination and OR all its elements with the `[+|]`

operator. This gives a decimal result so we convert
it to binary digits with `.base(2)`

. Testing if the binary representation ends in 0 is easy with `.ends-with(0)`

. If the number of
suitable elements found by `.grep()`

is greater than 0, `say`

prints out `True`

or otherwise `False`

.

For Perl, we have to provide our own implementations of `.combinations()`

and `[+|]`

. The former has appeared in many previous challenges but the latter is new. The function below remedies the lack.

`bitwiseOR()`

takes as input a reference to a list for no other reason than that `combinations()`

returns each combination as
a list reference. I will change that at some point.

```
sub bitwiseOR($listref) {
```

Especially because I immediately convert it back to a list anyway.

```
my @list = @{$listref};
```

First `$result`

is initialized with the first element of the list which is then removed.

```
my $result = shift @list;
```

Then every other element in `@list`

is ORed with `$result`

.

```
for my $elem (@list) {
$result |= $elem;
}
```

Finally, `$result`

is returned.

```
return $result;
}
```

Now we can (mostly) follow the same algorithm as Raku.

```
my @ints = @ARGV;
```

Because my version of `combinations()`

doesn't support ranges like in Raku, a double for loop is needed.

```
for my $i (2 .. scalar @ints) {
for my $combo (combinations(\@ints, $i)) {
if ((split //, sprintf("%b", bitwiseOR($combo)))[-1] == '0') {
```

We don't need all OR combinations ending in 0; just one is enough for us to be able ro determine truth or falsefood.
So if we find one, we print `true`

and stop processing early. (Unlike Raku.)

```
say 'true';
exit(0);
}
}
}
```

If we didn't find any suitable combinations, we print `false`

.

```
say 'false';
```

#### Challenge 2:

**Distribute Elements**

You are given an array of distinct integers,

`@ints`

.Write a script to distribute the elements as described below:

```
1) Put the 1st element of the given array to a new array @arr1.
2) Put the 2nd element of the given array to a new array @arr2.
```

Once you have one element in each arrays,

`@arr1`

and`@arr2`

, then follow the rule below:

```
If the last element of the array @arr1 is greater than the last
element of the array @arr2 then add the first element of the
given array to @arr1 otherwise to the array @arr2.
```

When done distribution, return the concatenated arrays.

`@arr1`

and`@arr2`

.

##### Example 1

```
Input: @ints = (2, 1, 3, 4, 5)
Output: (2, 3, 4, 5, 1)
1st operation:
Add 1 to @arr1 = (2)
2nd operation:
Add 2 to @arr2 = (1)
3rd operation:
Now the last element of @arr1 is greater than the last element
of @arr2, add 3 to @arr1 = (2, 3).
4th operation:
Again the last element of @arr1 is greate than the last element
of @arr2, add 4 to @arr1 = (2, 3, 4)
5th operation:
Finally, the last element of @arr1 is again greater than the last
element of @arr2, add 5 to @arr1 = (2, 3, 4, 5)
Mow we have two arrays:
@arr1 = (2, 3, 4, 5)
@arr2 = (1)
Concatenate the two arrays and return the final array: (2, 3, 4, 5, 1).
```

##### Example 2

```
Input: @ints = (3, 2, 4)
Output: (3, 4, 2)
1st operation:
Add 1 to @arr1 = (3)
2nd operation:
Add 2 to @arr2 = (2)
3rd operation:
Now the last element of @arr1 is greater than the last element
of @arr2, add 4 to @arr1 = (3, 4).
Mow we have two arrays:
@arr1 = (3, 4)
@arr2 = (2)
Concatenate the two arrays and return the final array: (3, 4, 2).
```

##### Example 3

```
Input: @ints = (5, 4, 3 ,8)
Output: (5, 3, 4, 8)
1st operation:
Add 1 to @arr1 = (5)
2nd operation:
Add 2 to @arr2 = (4)
3rd operation:
Now the last element of @arr1 is greater than the last element
of @arr2, add 3 to @arr1 = (5, 3).
4th operation:
Again the last element of @arr2 is greate than the last element
of @arr1, add 8 to @arr2 = (4, 8)
Mow we have two arrays:
@arr1 = (5, 3)
@arr2 = (4, 8)
Concatenate the two arrays and return the final array: (5, 3, 4, 8).
```

The spec is sufficiently clear that we can translate it into Raku almost verbatim.

Put the 1st element of the given array to a new array @arr1.

```
my @arr1 = @ints.shift;
```

Put the 2nd element of the given array to a new array @arr2.

```
my @arr2 = @ints.shift;
```

If the last element of the array `@arr1`

is greater than the last element of the array `@arr2`

then add the first element of the given array to `@arr1`

otherwise to the array `@arr2`

.

(Note: I used `.keys()`

here to traverse through `@ints`

by index. But in hindsight, that seems pointless. I could
just as easily have traversed through the elements themselves.)

```
for @ints.keys -> $k {
```

(Also for readabilities' sake, I should have written this as an `if-else`

statement rather than use the ternary operator.)

```
@arr1[*-1] > @arr2[*-1] ?? @arr1.push(@ints[$k]) !! @arr2.push(@ints[$k]);
}
```

Return the concatenated arrays. `@arr1`

and `@arr2`

.

(The additional code is merely to make the output pretty.)

```
say q{(}, @arr1.push(| @arr2).join(q{, }), q{)};
```

This is the Perl version. For once, we didn't need any additional code to mimic Raku features. It shares the same faults as the Raku version.

```
my @ints = @ARGV;
my @arr1 = shift @ints;
my @arr2 = shift @ints;
for my $k (keys @ints) {
if ($arr1[-1] > $arr2[-1]) {
push @arr1, $ints[$k];
} else {
push @arr2, $ints[$k];
}
}
push @arr1, @arr2;
say q{(}, (join q{, }, @arr1), q{)};
```