### Perl Weekly Challenge: Week 157

#### Challenge 1:

**Pythagorean Means**

You are given a set of integers.

Write a script to compute all three `Pythagorean Means`

i.e Arithmetic Mean, Geometric Mean and Harmonic Mean of the given set of integers. Please refer to wikipedia page for more informations.

##### Example 1:

```
Input: @n = (1,3,5,6,9)
Output: AM = 4.8, GM = 3.8, HM = 2.8
```

##### Example 2:

```
Input: @n = (2,4,6,8,10)
Output: AM = 6.0, GM = 5.2, HM = 4.4
```

##### Example 3:

```
Input: @n = (1,2,3,4,5)
Output: AM = 3.0, GM = 2.6, HM = 2.2
```

All I needed to do for this problem was to translate the formulas given in the Wikipedia article into Raku and Perl. So there isn't really much to say about the code.

```
my $am = ([+] @n) / @n.elems;
```

Well ok one thing; From the examples it would seem that we only should output one decimal digit of precision. `.round()`

takes care
of that.

```
my $gm = ((([*] @n).abs) ** (-1 / -@n.elems)).round(0.1);
my $hm = (@n.elems / ([+] @n.map({ 1 / $_; }))).round(0.1);
say "AM = $am, GM = $gm, HM = $hm";
```

For Perl, I used `nearest()`

from `Math::Round`

to do the rounding. I also reused `sum()`

and
`product()`

from previous challenges to deal with the lack of `[+]`

and `[*]`

.

```
my $am = sum(\@n) / scalar @n;
my $gm = nearest(0.1, (abs product(\@n)) ** (-1 / scalar -@n));
my $hm = nearest(0.1, scalar @n / sum([map { 1 / $_; } @n]));
say "AM = $am, GM = $gm, HM = $hm";
```

#### Challenge 2:

**Brazilian Number**

You are given a number

`$n > 3`

.Write a script to find out if the given number is a

`Brazilian Number`

.A positive integer number N has at least one natural number B where 1 < B < N-1 where the representation of N in base B has same digits.

##### Example 1:

```
Input: $n = 7
Output: 1
Since 7 in base 2 is 111.
```

##### Example 2:

```
Input: $n = 6
Output: 0
Since 6 in base 2 is 110,
6 in base 3 is 20 and
6 in base 4 is 12.
```

##### Example 3:

```
Input: $n = 8
Output: 1
Since 8 in base 3 is 22.
```

This was another easy one for Raku:

```
for 2 ..^ $n - 1 -> $B {
my @digits = $n.base($B).comb;
```

If all the digits are the same as the first one, we print 1 and finish the script.

```
if @digits.all == @digits[0] {
say 1;
exit;
}
}
```

If we've gone through the full range of bases, `$n`

is not a Brazilian number so we print 0.

```
say 0;
```

Perl required a replacement for `.base()`

. Luckily I had written such a thing way back in Challenge 43. That function returned a string so I had to make a slight modification to
make it return a number. As it has been a long time, here it is:

```
sub base {
my ($number, $base) = @_;
my @digits = (0 .. 9, 'A' .. 'Z');
my @result;
while ($number > ($base - 1)) {
my $digit = $number % $base;
push @result, $digits[$digit];
$number /= $base;
}
push @result, $digits[$number];
return 0 + (join '', reverse @result);
}
```

Back to the main part of the script...

```
my $n = shift // die "Need an integer.\n";
for my $B (2 .. $n - 2) {
my @digits = split //, base($n, $B);
```

As a workaround for no `.all()`

, I grepped for a digit that was *not* the same as the first digit.

```
if (!grep { $_ != $digits[0] } @digits) {
say 1;
exit;
}
}
say 0;
```