# Weekly Challenge #149 and A Fix, Maybe, to #148

### Fixing an Old Task

Abigail read my blog post and pointed out that the given first correct answer of #148 Task 2, `(2,1,5)`

was not showing up, and when he ran my `test_ardano`

function against it, it didn’t return `1`

, but rather `1.00000000000000000011`

.

I think the *only* time I regularly do math like this is in the Challenge, which is good because it makes me use ideas I don’t touch regularly, but it does get me in places I can’t negotiate out of. It’s a known thing that IEEE 754 math has hairy edge cases, and I’m *guessing* that I’m hanging up on that. I changed my `cuberoot`

function to limit the number of significant digits —

```
sub cuberoot ($n ) { return sprintf '%.06f', $n**( 1 / 3 ) }
```

— but that seems like a hackish *“just make it work!”* solution rather than really understanding where the problem is and fixing that. I admit that. When the Reviews come around, I’ll have to read to see the better Cardano Triplets solutions.

Thanks to Abigail for pointing out the problem.

### TASK #1 › Fibonacci Digit Sum

Submitted by: Roger Bell_West Given an input $N, generate the first $N numbers for which the sum of their digits is a Fibonacci number.

I got this to an acceptable point fairly quickly. I use `split`

to separate the numbers into digits, `sum0`

from List::Util because I am always paranoid about empty strings and a function that finds the Fibonacci number that is not less than the given number, which would be the `sum0`

of the digits. If the function returns a number that *is* sum, then there we go! We append it to an array, and stop looking when the array is big enough.

#### Show Me The Code!

```
#!/usr/bin/env perl
use strict;
use warnings;
use feature qw{ say postderef signatures state };
no warnings qw{ experimental };
use Getopt::Long;
use List::Util qw{ sum0 max };
my $N = 20;
GetOptions( 'n=i' => \$N, );
my @fib = first_60_fib();
my %fib = map { $_ => 1 } @fib;
my @x;
my $n = 0;
while ( scalar @x < $N ) {
my $sd = sum_of_digits($n);
my $f = $fib{$sd} || 0;
push @x, $n if $f;
$n++;
}
say join ' ', @x;
sub first_60_fib() {
my @n;
push @n, 0;
push @n, 1;
while ( scalar @n < 60 ) {
push @n, $n[-1] + $n[-2];
}
return @n;
}
sub sum_of_digits ( $n ) {
return sum0 split //, $n;
}
```

```
$ ./ch-1.pl -n 30
0 1 2 3 5 8 10 11 12 14 17 20 21 23 26 30 32 35 41 44 49 50 53 58 62 67 71 76 80 85
```

### TASK #2 › Largest Square

Submitted by: Roger Bell_West Given a number base, derive the largest perfect square with no repeated digits and return it as a string. (For base>10, use ‘A’..‘Z’.)

This is giving me problems.

There are parts that are fairly simple. You get the 36 characters we can get with `my @range = ( 0 .. 9, 'A' .. 'Z' )`

, and you can get the right characters for any base with `my @range_by_base = @range[0..$base-1]`

. The highest possible correct number becomes `join '', reverse @range_by_base`

.

I found that many of the Base Conversion modules convert from and to common CS-related bases — 2, 4, 8, 16, 32, etc. — but for this task, we want to convert into and out of any base, and I found that Math::BaseCalc does that well.

Using `state`

, I made functions that convert back and forth, and hold onto the numbers, so we don’t have to re-generate `100`

in base 19 twice. (In writing this, I’m second-guessing the utility of that, but I’ve done the cool thing, so eh?)

But there’s still going from **9,876,543,210** to **1**, in the case of base 10. I am doing it with a for loop and an implicit 10-million-entry list, and that’s killing me. I think that a while loop instead, like `while ($n > 1) { $n-- }`

might be it. In fact, it’s looking promising (and not segfaulting) as I write this. When and if I solve it, I’ll blog it separately.