# ETOOBUSY ðŸš€ minimal blogging for the impatient

# PWC199 - Good Triplets

**TL;DR**

On with TASK #2 from The Weekly Challenge #199. Enjoy!

# The challenge

You are given an array of integers,

`@array`

and three integers`$x`

,`$y`

,`$z`

.Write a script to find out total

`Good Triplets`

in the given array.A triplet array[i], array[j], array[k] is good if it satisfies the following conditions:

`a) 0 <= i < j < k <= n (size of given array) b) abs(array[i] - array[j]) <= x c) abs(array[j] - array[k]) <= y d) abs(array[i] - array[k]) <= z`

Example 1`Input: @array = (3,0,1,1,9,7) and $x = 7, $y = 2, $z = 3 Output: 4 Good Triplets are as below: (3,0,1) where (i=0, j=1, k=2) (3,0,1) where (i=0, j=1, k=3) (3,1,1) where (i=0, j=2, k=3) (0,1,1) where (i=1, j=2, k=3)`

Example 2`Input: @array = (1,1,2,2,3) and $x = 0, $y = 0, $z = 1 Output: 0`

# The questions

Just to nit-pick a bit, Iâ€™d argue that condition *a)* is technically
correct although it might be misleading as it is a little too broad. It
allows one excess element from the array (both indexes `0`

and `n`

seem
to be included in the range).

Iâ€™ll stop at `k = n - 1`

anyway.

# The solution

Iâ€™m getting too old for this sâ€¦*tuff*.

I came out with the obvious $O(N^3)$ algorithm, but *I know* that there
must be something better.

Anyway.

Perl goes first this time:

```
#!/usr/bin/env perl
use v5.24;
use warnings;
use experimental 'signatures';
no warnings 'experimental::signatures';
my ($x, $y, $z, @list) = @ARGV ? @ARGV : (7, 2, 3, 3, 0, 1, 1, 9, 7);
say good_triplets($x, $y, $z, @list);
sub good_triplets ($x, $y, $z, @list) {
my $count = 0;
for my $i (0 .. $#list - 2) {
for my $j ($i + 1 .. $#list - 1) {
next if abs($list[$i] - $list[$j]) > $x;
for my $k ($j + 1 .. $#list) {
next if abs($list[$j] - $list[$k]) > $y
|| abs($list[$i] - $list[$k]) > $z;
++$count;
}
}
}
return $count;
}
```

Thenâ€¦ Raku:

```
#!/usr/bin/env raku
use v6;
sub MAIN ($x, $y, $z, *@list) { put good-triplets($x, $y, $z, @list) }
sub good-triplets ($x, $y, $z, *@list) {
return [+] gather for 0 .. (@list - 3) -> \i {
for (i + 1) .. (@list - 2) -> \j {
next if (@list[i] - @list[j]).abs > $x;
for (j + 1) ..^ @list -> \k {
next if (@list[j] - @list[k]).abs > $y
|| (@list[i] - @list[k]).abs > $z;
take 1;
}
}
};
}
```

Yes, it leaves a bitter taste. Letâ€™s get some candy and move on.

Cheers!

*Comments? Octodon, Twitter, GitHub, Reddit, or drop me a line!*