Originally published on 05 November 2020

The latest installment of the Perl Weekly Challenge just dropped so I thought I would take a crack at it. Please note that the challenge is still currently open (as of date of publishing) in case you are participating.

Task #1 asks the following:

You are given an array of real numbers greater than zero.

Write a script to find if there exists a triplet

`(a,b,c)`

such that`1 < a+b+c < 2`

. Print 1 if you succeed otherwise 0.

`Example 1:`

`Input: @R = (1.2, 0.4, 0.1, 2.5)`

`Output: 1 as 1 < 1.2 + 0.4 + 0.1 < 2`

`Example 2:`

`Input: @R = (0.2, 1.5, 0.9, 1.1)`

`Output: 0`

`Example 3:`

`Input: @R = (0.5, 1.1, 0.3, 0.7)`

`Output: 1 as 1 < 0.5 + 1.1 + 0.3 < 2`

For the purposes of this task, I assumed that the array of real numbers would be provided in quotes as an argument to the script when you run it:

`$ ./ch-1.pl "0.5, 1.1, 0.3, 0.7, 0.1, 0.3, 0.2"`

Therefore, to get the numbers into my `@data`

array, I used the `split`

operator on `$ARGV[0]`

.

I’m afraid I may have been a bit lazy on this challenge and just used a brute-force approach to go through all of the three-number combinations (e.g. *k=3*) using the CPAN module `Algorithm::Combinatorics`

. Also, instead of just returning one combination that meets the triplet requirement, I decided to return all possible combinations if there are more than one. Putting it all together, I came up with:

```
#!/usr/local/bin/perl
use warnings;
use strict;
use feature 'say';
use Algorithm::Combinatorics qw/combinations permutations/;
use List::Util qw/sum/;
# run program as:
# $ ./ch-1.pl "0.5, 1.1, 0.3, 0.7"
my @data = split /, /, $ARGV[0];
my $citer = combinations(\@data, 3);
my $notFound = 1;
while (my $c = $citer->next) {
if (sum(@$c) > 1 && sum(@$c) < 2) {
say "found triplet such that 1 < ", join( " + ", @$c), " < 2";
$notFound = 0;
}
}
say "no triplets found such that 1 < a+b+c < 2" if $notFound;
```

Task #2 says:

You are given a positive integer

`$N`

.

Write a script to find if it can be expressed as

`a ^ b`

where`a > 0`

and`b > 1`

. Print 1 if you succeed otherwise 0.

`Example 1:`

`Input: 8`

`Output: 1 as 8 = 2 ^ 3`

`Example 2:`

`Input: 15`

`Output: 0`

`Example 3:`

`Input: 125`

`Output: 1 as 125 = 5 ^ 3`

Again, I’m not really proud of this effort as I just came up with another brute-force solution. For each number, I find the nth root (represented by the variable `$b`

) from 2 up to the number itself. I then round the result (stored in the variable `$a`

) down using the `floor`

function and raise it back up to the power of `$b`

. If the result equals the number we were given, we have found a solution and then print the result to `STDOUT`

. This works because only roots that result in an integer equal the result of taking their `floor`

.

The resulting script can be written as:

```
#!/usr/local/bin/perl
use v5.10;
use POSIX;
use strict;
use warnings;
my ($a, $b,);
my $number = $ARGV[0];
my $notFound = 1;
for (my $b = 2; $b < $number; $b++) {
$a = $number ** (1 / $b);
if (floor($a) ** $b == $number) {
say floor($a), " ^ ", $b, " = ", $number;
$notFound = 0;
}
}
say "0" if $notFound;
```

I’ll be interested in what others come up with as these solutions are not efficient for large numbers or arrays but they were easy to come up with, code and test. If you are interested in participating, please remember that the entry deadline is 23:59 GMT Sunday 08 November 2020. Good luck!