Recognizing Abundant, Deficient, and Perfect Numbers

Recognizing Abundant, Deficient, and Perfect Numbers

Ok, this post falls into the "I'll never actually use this again" category, which frankly, my normal readers know happens all the time, but it was a fun little diversion and a reminder of why I used to love math so much.

Yesterday I found out that one of my kids' homework was to look at a set of numbers and determine if they were abundant, deficient, or perfect. Right now you are probably (at least I know I was) asking, "what in the actual heck is that???"

A quick bit of Googling turned up this explainer that basically boils it down to a simple principal.

Given a number, find all the divisors of that number, excluding the number itself, and add them up. If the result is less than the original number, it is deficient. If the number is equal, it's perfect. Finally, if the sum is over the input, it's abundant.

So for example, 6 is considered perfect because the divisors, 1+2+3, equal 6 when added together. 5, which only has a divisor of 1 (remember, you exclude the number itself) is deficient. 12 is abundant (1+2+3+4+6 == 16).

You can read more, and see more variations, on the Encyclopedia.com article if you would like. Honestly, I see absolutely see use for this, but I thought - why not whip up a quick demo of this in BoxLang

Version One

The first version I built uses one main method to get divisors, minus the input itself, with a special case for 1:

function getDivisors(n) {
    local.divisors = [];
	if(n === 1) return divisors;
    for (local.i = 1; i <= ceiling(abs(n)/2); i++) {
      if (n % i == 0) {
        divisors.push(i);
      }
    }
    return divisors;
}

The result of this is an array of divisors. I then built one function each for the three types of numbers:

function isPerfectNumber(required int x) {
	local.divisors = getDivisors(x);
	local.sum = divisors.reduce((prev, cur) => return cur + prev, 0);
	return sum == x;
}

function isAbundantNumber(required int x) {
	local.divisors = getDivisors(x);
	local.sum = divisors.reduce((prev, cur) => return cur + prev, 0);
	return sum > x;
}

function isDeficientNumber(required int x) {
	local.divisors = getDivisors(x);
	local.sum = divisors.reduce((prev, cur) => return cur + prev, 0);
	return sum < x;
}

Fairly simple, right? I whipped up a quick test:

for(i=1;i<30;i++) {
	println("is #i# a perfect number? #isPerfectNumber(i)#");
	println("is #i# an abundant number? #isAbundantNumber(i)#");
	println("is #i# a deficient number? #isDeficientNumber(i)#");
	println("");
}

And you can try this yourself below.

Finally, given that a number must be one of three types, it's probably easier to just have one function:

function getNumberType(required int x) {
	local.divisors = getDivisors(x);
	local.sum = divisors.reduce((prev, cur) => return cur + prev, 0);
	if(sum < x) return 'deficient';
	if(sum === x) return 'perfect';
	return 'abundant';
}

You can try this below:

Image from the National Gallery of Art, Cats and Kittens, by an unknown artist.