### Perl Weekly Challenge: Week 51

#### Challenge 1:

3 SumGiven an array

`@L`

of integers. Write a script to find all uniquetripletssuch thata + b + cis same as the given target`T`

. Also make surea <= b <= c.Here is wiki page for more information.

Example:

`@L = (-25, -10, -7, -3, 2, 4, 8, 10);`

One such triplet for target

`0`

i.e.-10 + 2 + 8 = 0.

Here's the Perl version first. I decided that my script should be able to take
the values for `$T`

and `@L`

from the command line.

```
my $T = shift;
my @L = @ARGV;
```

The wikipedia page referenced in the task description gives an algorithm to solve this problem which seems more complicated then it needs to be. This is what I ended up doing.

First I found all the three-element combinations from `@L`

. I reused the `combinations()`

routine I had developed for challenge 38

```
for my $combo (combinations(\@L, 3)) {
```

Then I sorted the combination to preserve the `a <= b <= c`

relation the task requires.

```
my @triplet = sort{ $a <=> $b } @{$combo};
```

I added up the values of the three elements.

```
my $total = 0;
for my $elem (@triplet) {
$total += $elem;
}
```

And if the sum was equal to `$T`

, I printed the combination out.

```
if ($total == $T) {
say join q{ }, @triplet;
}
```

This is the Raku version. Notice how much less code it needs to do the same thing?

```
multi sub MAIN($T, *@L) {
for @L.combinations(3) -> @combo {
my @triplet = @combo.sort;
my $total = [+] @triplet;
if ($total == $T) {
@triplet.join(q{ }).say;
}
}
}
```

#### Challenge 2:

Colorful NumberWrite a script to display all

Colorful Numberwith 3 digits.A number can be declare

Colorful Numberwhere all the products of consecutive subsets of digit are different.For example,

263is aColorful Numbersince2, 6, 3, 2x6, 6x3, 2x6x3are unique.

The problem can be summarized in code like this:

```
for my $n (grep { isColorful($_) } 100 .. 999) {
say $n;
}
```

But what does that `isColorful()`

function look like?

```
sub isColorful {
my ($n) = @_;
```

We are going to do a lot of manipulation of individual digits so first I split
the prospective colorful number into the `@digits`

array. I created another array,
`@products`

to hold the results of all the intermediate calculations. It's initial
contents are the `@digits`

. The best way to count up the frequency elements occur
in an array is by assigning them to keys in a hash. So `%subsets`

is provided for that.

```
my %subsets;
my @digits = split //, $n;
my @products = @digits;
```

Then the results of the two and three digit multiplications are added to `@products`

.

```
push @products, $digits[0] * $digits[1];
push @products, $digits[1] * $digits[2];
push @products, $digits[0] * $digits[1] * $digits[2];
```

Finally all the elements of `@products`

are mapped to keys in `%subsets`

.

```
map { $subsets{$_}++ } @products;
```

If any key in `%subsets`

has a value greater than one, we know that element occured
more than once in @products and therefore this is not a colorful number.

```
return !grep { $_ > 1 } values %subsets;
}
```

The Raku version is very similar. Unusually, I didn't even find any major ways
to shorten the code with Raku features except perhaps the use of `.all()`

instead of
`grep()`

in the return statement.

```
sub isColorful($n) {
my %subsets;
my @digits = $n.comb;
my @products = @digits;
@products.push(@digits[0] * @digits[1]);
@products.push(@digits[1] * @digits[2]);
@products.push(@digits[0] * @digits[1] * @digits[2]);
@products.map({ %subsets{$_}++ });
return %subsets.values.all == 1;
}
```