# ETOOBUSY ðŸš€ minimal blogging for the impatient

# PWC171 - Abundant Number

**TL;DR**

Here we are with TASK #1 from The Weekly Challenge #171. Enjoy!

# The challenge

Write a script to generate first

`20 Abundant Odd Numbers`

.According to wikipedia,

A number n for which the sum of divisors Ïƒ(n) > 2n, or, equivalently, the sum of proper divisors (or aliquot sum) s(n) > n.

For example,

`945`

is the first`Abundant Odd Number`

.`Sum of divisors: 1 + 3 + 5 + 7 + 9 + 15 + 21 + 27 + 35 + 45 + 63 + 105 + 135 + 189 + 315 = 975`

# The questions

Iâ€™m always tempted to ask about what *first* means in these challenges.
In these number theory stuff, it usually means *least non-negative
ones*, but itâ€™s always stated as *first* and this probably leaves space
toâ€¦ *is it good to read it as the first ones that I can find?*.

# The solution

The question is not pure nitpicking this time. As the wikipedia page
explains, every (integer) multiple of an abundant number is itself an
abundant number, so multiplying `945`

times `1`

, `3`

, â€¦, `39`

(odds
numbers between `0`

and `40`

) will bot give us an odd number *and* an
abundant number. So easy to calculate and so light on the environment.

Alas, letâ€™s take the parsimonious path and find the lowest ones instead, starting with Raku:

```
#!/usr/bin/env raku
use v6;
sub MAIN (Int:D $n where * > 0 = 20) {
my @abundants;
my $candidate = 945;
while @abundants < $n {
@abundants.push: $candidate if is-abundant($candidate);
$candidate += 2;
}
put @abundants.join(', ');
}
sub is-abundant (Int:D $n) { $n < [+] proper-positive-divisors($n) }
sub proper-positive-divisors (Int:D $n is copy where * != 0) {
$n = $n.abs;
my (@lows, @highs) = 1,;
my ($lo, $hi) = (2, $n);
while $lo < $hi {
if $n %% $lo {
@lows.push: $lo;
$hi = ($n / $lo).Int;
@highs.unshift: $hi if $hi != $lo;
}
++$lo;
}
return [@lows.Slip, @highs.Slip];
}
```

Itâ€™s pure composition of bricks. Sub `proper-positive-divisors`

takes
care to give us allâ€¦ *proper, positive divisors*. This is used inside
the check function `is-abundant`

to test the condition. An outer loop
(the `while`

in the `MAIN`

sub) takes care of finding out the lowest
*EHR* first 20.

The function for finding divisors is marginally interesting. As soon as
we find a divisor, we also find its complementary in the product to get
to the original number, so we can accumulate divisors from the bottom
*and* from the top. At this point, thereâ€™s no reason to go beyond when
the lower candidate gets past its complementary.

Itâ€™s interesting that this approach *might* not give us any edge at all
with respect to iterating more and not caring about the complementaries.
This is because - more or less! - there is a division check with the
`%%`

operator *and* a real division. Assuming the two take the same
resources, we might just as well ignore the complementary ang move on.

The Perl counterpart is a faithful translation:

```
#!/usr/bin/env perl
use v5.24;
use warnings;
use experimental 'signatures';
no warnings 'experimental::signatures';
use List::Util 'sum';
my $n = shift // 20;
my @abundants;
my $candidate = 945;
while (@abundants < $n) {
push @abundants, $candidate if is_abundant($candidate);
$candidate += 2;
}
say join ', ', @abundants;
sub is_abundant ($n) { $n < sum(proper_positive_divisors($n)) }
sub proper_positive_divisors ($n) {
return unless $n;
$n = -$n if $n < 0;
my (@lows, @highs) = (1);
my ($lo, $hi) = (2, $n);
while ($lo < $hi) {
if ($n % $lo == 0) {
push @lows, $lo;
$hi = int($n / $lo);
unshift @highs, $hi if $hi != $lo;
}
++$lo;
}
return (@lows, @highs);
}
```

It feels less sophisticated but heck does this feel natural!

Stay safe folks!

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