### Perl Weekly Challenge: Week 163

#### Challenge 1:

**Sum Bitwise Operators**

You are given a list of positive numbers,

`@n`

.Write script to calculate the sum of bitwise & operator for all unique pairs.

##### Example 1:

```
Input: @n = (1, 2, 3)
Output: 3
Since (1 & 2) + (2 & 3) + (1 & 3) => 0 + 2 + 1 => 3.
```

##### Example 2:

```
Input: @n = (2, 3, 4)
Output: 2
Since (2 & 3) + (2 & 4) + (3 & 4) => 2 + 0 + 0 => 2.
```

In Raku we can solve this with a one-liner.

```
@*ARGS.combinations(2).map({ [+&] $_ }).sum.say;
```

`@*ARGS`

are the arguments passed on the command line. These should be a list of positive numbers though I'm not actually checking that. We apply `.combinations(2)`

to them to get unique pairs. Then `.map()`

is used to apply bitwise and to each pair. (bitwise and is `+&`

in Raku not just `&`

which always trips me up.) I could have expressed this as `$_[0] +& $_[1]`

but decided to use the hyperoperator `[+&]`

instead. It just reads better IMO. At this point, we have a list of results of each and operation. These are totalled with `.sum()`

. I could have used `[+]`

but this allows me to continue chaining

In Perl, we have to be a bit more verbose as we are missing `.sum()`

and `.combinations()`

but I already had replacement functions for them and armed with those, the core part of the Perl solution is also one line.

```
say sum([map { $_->[0] & $_->[1] } combinations(\@ARGV, 2) ]);
```

#### Challenge 2:

**Summations**

You are given a list of positive numbers,

`@n`

.Write a script to find out the summations as described below.

##### Example 1:

```
Input: @n = (1, 2, 3, 4, 5)
Output: 42
1 2 3 4 5
2 5 9 14
5 14 28
14 42
42
The nth Row starts with the second element of the (n-1)th row.
The following element is sum of all elements except first element of previous row.
You stop once you have just one element in the row.
```

##### Example 2:

```
Input: @n = (1, 3, 5, 7, 9)
Output: 70
1 3 5 7 9
3 8 15 24
8 23 47
23 70
70
```

This one took me a little while to understand but ultimately proved to be quite straightforward to solve. According to the spec, the nth row begins with the (n-1)th element of the previous row. So we start the script with
all the elements of the input except the first. I've called this new array `@previous`

but in hindsight `@current`

would have been more appropriate.

```
my @previous = @n[1 .. *];
```

There is also a variable to store the running total.

```
my $total;
```

Now as long as there is atleast one element left in `@previous`

...

```
while @previous.elems {
```

We initalize `$total`

to the value of the first element.

```
$total = @previous[0];
```

And set up an array to hold the next line. It is initialized with `$total`

.

```
my @next = ( $total );
```

Then for each of the remaining elements in `@previous`

, we add its value to `$total`

and
add the new value of `$total`

to `@next`

.

```
for 1 ..^ @previous.elems -> $i {
$total += @previous[$i];
@next.push($total);
}
```

Finally, we make the new value of `@previous`

equal to all the elements of `@next`

except the
first one.

```
@previous = @next[1 .. *];
}
```

After this loop finishes, `$total`

contains the final answer so we print it.

```
say $total;
```

For once, Perl has everything we need to translate the Raku code above. The syntax isn't even particularly ungainly compared to the Raku version.

```
my @previous = @n[1 .. $#n];
my $total;
while (scalar @previous) {
$total = $previous[0];
my @next = ( $total );
for my $i (1 .. scalar @previous - 1) {
$total += $previous[$i];
push @next, $total;
}
@previous = @next[1 .. $#next];
}
say $total;
```