40
\$\begingroup\$

An Abundant number is any number where the sum of its proper divisors is greater than the original number. For example, the proper divisors of 12 are:

1, 2, 3, 4, 6

And summing these results in 16. Since 16 is larger than 12, 12 is abundant. Note that this does not include "Perfect numbers", e.g. numbers that are equal to the sum of its proper divisors, such as 6 and 28.

Your task for today is to write a program or function that determines if a number is abundant or not. Your program should take a single integer as input, and output a truthy/falsy value depending on whether it is abundant or not. You can assume that the input will always be valid and greater than 0, so for bad inputs, undefined behavior is fine.

You may take your input and output in any reasonable format, for example STDIN/STDOUT, files, or arguments/return values would all be acceptable.

For reference, here are the abundant numbers up to 100:

12,
18,
20,
24,
30,
36,
40,
42,
48,
54,
56,
60,
66,
70,
72,
78,
80,
84,
88,
90,
96,
100

And more can be found on A005101

Since this is , standard loopholes are denied, and try to write the shortest possible code you can in whichever language you happen to choose!

\$\endgroup\$
  • 11
    \$\begingroup\$ "the first odd abundant is 945 = 3^3*5*7, the 232nd abundant number!" \$\endgroup\$ – mbomb007 Feb 21 '17 at 14:29
  • \$\begingroup\$ The asymptotic density of abundant numbers is somewhere within the interval [0.24761748, 0.24764422]. Calculated using the source code included in this paper. \$\endgroup\$ – Deadcode Jan 25 at 22:20
  • 1
    \$\begingroup\$ I am trying to do this in Geometry Dash. It's a nightmare \$\endgroup\$ – MilkyWay90 Jan 29 at 3:25

55 Answers 55

10
\$\begingroup\$

Jelly, 3 bytes

Æṣ>

Try it online!

How it works

Æṣ>  Main link. Argument: n

Æs   Get the proper divisor sum of n.
  >  Test if the result is greater than n.
\$\endgroup\$
3
\$\begingroup\$

MATL, 6 bytes

Z\sGE>

Outputs 1 for abundant numbers, 0 otherwise.

How it works

Z\      % list the divisors of the implicit input
s       % add them
G       % push the input again
E       % double it
>       % compare
        % implicitly display result
\$\endgroup\$
8
\$\begingroup\$

05AB1E, 5 4 bytes

-1 bytes thanks to scottinet

ѨO‹

Try it online! or Try 0 to 100

\$\endgroup\$
  • \$\begingroup\$ @scottinet Nice! \$\endgroup\$ – Riley Sep 12 '17 at 15:50
2
\$\begingroup\$

RProgN, 8 Bytes

~_]k+2/<

Explained

~_]k+2/<
~           # Zero Space Segment
 _          # Convert the input to an integer
  ]         # Duplicate the input on the stack
   k+       # Get the sum of the divisors of the top of the stack
     2/     # Divded by 2
       <    # Is the Input less than the sum of its divisors/2.

Try it online!

\$\endgroup\$
10
\$\begingroup\$

Python, 44 bytes

lambda n:sum(i*(n%i<1)for i in range(1,n))>n

Try it online!

\$\endgroup\$
  • \$\begingroup\$ It's a shame you can't do range(n). That pesky modulus by zero \$\endgroup\$ – DJMcMayhem Feb 21 '17 at 1:44
5
\$\begingroup\$

Actually, 5 bytes

;÷Σ½>

Try it online!

;     # Duplicate input
 ÷    # Get divisors
  Σ   # Sum
   ½  # Divide by 2 (float)
    > # Test is greater than input
\$\endgroup\$
27
\$\begingroup\$

Python 2, 41 40 bytes

n=k=j=input()
while~k<0:j-=1;k-=j>>n%j*n

Output is via exit code, so 0 is truthy and 1 is falsy.

Try it online!

How it works

After setting all of n, k, and j to the input from STDIN, we enter the while loop. Said loop will break as soon as -k - 1 = ~k ≥ 0, i.e., k ≤ -1 / k < 0.

In each iteration, we first decrement j to consider only proper divisors of n. If j is a divisor of n, n%j yields 0 and j >> n%j*n = j/20 = j gets subtracted from k. However, if j does not divide n, n%j is positive, so n%j*n is at least n > log2 j and j >> n%j*n = j / 2n%j*n = 0 is subtracted from k.

For abundant numbers, k will reach a negative value before or when j becomes 1, since the sum of n's proper divisors is strictly greater than n. In this case, we break out of the while loop and the program finishes normally.

However, if n is not abundant, j eventually reaches 0. In this case, n%j throws a ZeroDivisionError and the program exits with an error.

\$\endgroup\$
  • 4
    \$\begingroup\$ ~k<0 is fancy, but I think -1<k also does the trick ;) \$\endgroup\$ – Martin Ender Feb 21 '17 at 13:55
10
\$\begingroup\$

Mathematica, 17 bytes

Tr@Divisors@#>2#&

Explanation

Tr@                 The sum of the main diagonal of
   Divisors@         the list of divisors of
            #         the first argument
             >      is greater than
              2#      twice the first argument.
                &   End of function.
\$\endgroup\$
  • 1
    \$\begingroup\$ I'm surprised Mathematica has no built in for this.. \$\endgroup\$ – MrPaulch Feb 21 '17 at 17:08
  • 1
    \$\begingroup\$ @MrPaulch Considering the length of the program though, the builtin may very well be longer in name >.> \$\endgroup\$ – Conor O'Brien Feb 22 '17 at 1:51
  • 1
    \$\begingroup\$ @ConorO'Brien If it existed, it would probably be AbundantNumberQ, so it would save a couple bytes :) \$\endgroup\$ – ngenisis Feb 22 '17 at 1:54
4
\$\begingroup\$

PARI/GP, 15 bytes

n->sigma(n)>2*n

The variant n->sigma(n,-1)>2 is, unfortunately, longer.

\$\endgroup\$
12
\$\begingroup\$

Brachylog, 5 bytes

fk+>?

Try it online!

Explanation

f           Factors
 k          Knife: remove the last one (the input itself)
  +         Sum
   >?       Stricly greater than the Input
\$\endgroup\$
3
\$\begingroup\$

QBIC, 22 bytes

:[a/2|~a%b|\p=p+b}?p>a

This is an adaptation to the QBIC primality test. Instead of counting the divisors and checking if it's less than three, this sums the proper divisors. This runs only along half of 1 to n, where the primality test runs through 1 to n completely.

Explanation:

:       Get the input number, 'a'
[a/2|   FOR(b=1, b<=(a/2), b++)
~a%b    IF a MOD b != 0  --> QBasic registers a clean division  (0) as false. 
        The IF-branch ('|') therefor is empty, the code is in the ELSE branch ('\')
|\p=p+b THEN add b to runnning total p
}       Close all language constructs: IF/END IF, FOR/NEXT
?p>a    Print '-1' for abundant numbers, 0 otherwise.
\$\endgroup\$
3
\$\begingroup\$

Pure Bash, 37 bytes

for((;k++<$1;s+=$1%k?0:k)){((s>$1));}

Thanks to @Dennis for rearranging the code -- saving 6 bytes and eliminating the incidental output to stderr.

The input is passed as an argument.

The output is returned in the exit code: 0 for abundant, 1 for not abundant.

Output to stderr should be ignored.

Test runs:

for n in {1..100}; do if ./abundant "$n"; then echo $n; fi; done 2>/dev/null
12
18
20
24
30
36
40
42
48
54
56
60
66
70
72
78
80
84
88
90
96
100
\$\endgroup\$
7
\$\begingroup\$

Retina, 50 45 bytes

^(?!(1(?<=(?=(?(\3+$)((?>\2?)\3)))^(1+)))*1$)

Input in unary, output 1 for abundant numbers, 0 otherwise.

There is nothing Retina-specific about this solution. The above is a pure .NET regex which matches only abundant numbers.

Try it online! (Test suite that filters decimal input with the above regex.)

\$\endgroup\$
4
\$\begingroup\$

Java 8, 53 bytes ( a lot more if you include the ceremonial code )

return IntStream.range(1,n).filter(e->n%e<1).sum()>n;

Try it online

Explanation :

IntStream.range(1,n) \\ numbers from 1 to n-1
filter(e->n%e<1)     \\ filter in numbers that perfectly divide the number n
sum()>n              \\ sum and compare to original number
\$\endgroup\$
  • 4
    \$\begingroup\$ Great answer, but with Java 8 you must include the function in your byte-count. Then again, you can drop the return if I'm not mistaken, so it will be even shorter: n->IntStream.range(1,n).filter(e->n%e<1).sum()>n (not 100% if this is correct, I almost never program in Java 8). Welcome to PPCG! \$\endgroup\$ – Kevin Cruijssen Feb 21 '17 at 9:30
  • 1
    \$\begingroup\$ The correct count via standard count would be n->java.util.stream.IntStream.range(1,n).filter(e->n%e<1).sum()>n for 65 bytes (assuming I got the package right off the top of my head) \$\endgroup\$ – CAD97 Feb 21 '17 at 14:30
2
\$\begingroup\$

Batch, 84 bytes

@set/ak=%1*2
@for /l %%j in (1,1,%1)do @set/ak-=%%j*!(%1%%%%j)
@cmd/cset/a"%k%>>31

Outputs -1 for an abundant number, 0 otherwise. Works by subtracting all the factors from 2n and then shifting the result 31 places to extract the sign bit. Alternative formulation, also 84 bytes:

@set k=%1
@for /l %%j in (1,1,%1)do @set/ak-=%%j*!(%1%%%%j)
@if %k% lss -%1 echo 1

Outputs 1 for an abundant number. Works by subtracting all the factors from n and then comparing the result to to -n. (set/a is Batch's only way of doing arithmetic so I can't easily adjust the loop.)

\$\endgroup\$
  • 1
    \$\begingroup\$ "(%1%%%%j)" oh, batch :) \$\endgroup\$ – Bryan Boettcher Feb 21 '17 at 23:44
6
\$\begingroup\$

Retina, 34 bytes

Byte count assumes ISO 8859-1 encoding.

M!&`(1+)$(?<=^\1+)
1>`¶

^(1+)¶1\1

Input in unary, output 1 for abundant numbers, 0 otherwise.

Try it online!

Explanation

M!&`(1+)$(?<=^\1+)

We start by getting all divisors of the input. To do this, we return (!) all overlapping (&) matches (M) of the regex (1+)$(?<=^\1+). The regex matches some suffix of the input, provided that the entire input is a multiple of that suffix (which we ensure by trying to reach the beginning fo the string using only copies of the suffix). Due to the way the regex engine looks for matches, this will result a list of divisors in descending order (separated by linefeeds).

1>`¶

The stage itself simply matches linefeeds () and removes them. However, the 1> is a limit, which skips the first match. So this effectively adds together all divisors except the input itself. We end up with the input on the first line and the sum of all proper divisors on the second line.

^(1+)¶1\1

Finally, we try to match the at least one more 1 on the second line than we have on the first line. If that's the case, the sum of proper divisors exceeds the input. Retina counts the number of matches of this regex, which will be 1 for abundant numbers and 0 otherwise.

\$\endgroup\$
  • 1
    \$\begingroup\$ It's always amazed me how you can do math in retina. I'd love to see an explanation! :) \$\endgroup\$ – DJMcMayhem Feb 21 '17 at 14:49
  • 1
    \$\begingroup\$ @DJMcMayhem Sorry forgot to add that earlier. Done. \$\endgroup\$ – Martin Ender Feb 21 '17 at 14:55
0
\$\begingroup\$

Java 7, 69 68 bytes

Object c(int n){int s=0,i=1;for(;++i<=n/2;s+=n%i<1?i:0);return s>n;}

Explanation:

Object c(int n){                       // Boolean method with integer parameter
   int s = 0,                          // sum initialization
       i = 1;                          // counter initialization (starts at 2: i=1 and ++i becomes i=2)
   for(; ++i <= n/2; s += n % i < 1    // loop while (i <= n/2)
                           ? i         //   if (n % i == 0)
                           : 0);       //     r = r + i
   return s > n;                       // return sum > input
 }

Test code:

Try it here.

class M{
  static Object c(int n){int s=0,i=1;for(;++i<=n/2;s+=n%i<1?i:0);return s>n;}

  public static void main(String[] a){
    for(int i = 0; i <= 100; i++){
      System.out.print(i+": "+c(i) + ";  ");
    }
  }
}

Output:

0: false;  1: false;  2: false;  3: false;  4: false;  5: false;  6: false;  7: false;  8: false;  9: false;  10: false;  
11: false;  12: true;  13: false;  14: false;  15: false;  16: false;  17: false;  18: true;  19: false;  
20: true;  21: false;  22: false;  23: false;  24: true;  25: false;  26: false;  27: false;  28: false;  29: false;  
30: true;  31: false;  32: false;  33: false;  34: false;  35: false;  36: true;  37: false;  38: false;  39: false;  
40: true;  41: false;  42: true;  43: false;  44: false;  45: false;  46: false;  47: false;  48: true;  49: false;  
50: false;  51: false;  52: false;  53: false;  54: true;  55: false;  56: true;  57: false;  58: false;  59: false;  
60: true;  61: false;  62: false;  63: false;  64: false;  65: false;  66: true;  67: false;  68: false;  69: false;  
70: true;  71: false;  72: true;  73: false;  74: false;  75: false;  76: false;  77: false;  78: true;  79: false;  
80: true;  81: false;  82: false;  83: false;  84: true;  85: false;  86: false;  87: false;  88: true;  89: false;  
90: true;  91: false;  92: false;  93: false;  94: false;  95: false;  96: true;  97: false;  98: false;  99: false;  100: true;  
\$\endgroup\$
  • \$\begingroup\$ Sorry, I was looking at the main code in that part but the golfed code above. Reading failure. \$\endgroup\$ – user18932 Feb 22 '17 at 2:45
  • \$\begingroup\$ I am most likely overlooking something obvious, though I am curious: Why did you choose to use Object as opposed to bool? \$\endgroup\$ – Jonathan Frech Jan 22 at 23:14
  • \$\begingroup\$ @JonathanFrech In Java it's boolean, so it's 1 byte longer than Object :) Although nowadays I would just use a Java 8+ lambda, so Object c(int n) would be n->. \$\endgroup\$ – Kevin Cruijssen Jan 23 at 7:46
2
\$\begingroup\$

Perl 6, 72 24 bytes

{$_ <sum grep $_%%*,^$_}
  • Program argument: a.
  • Generate a list from 1..a.
  • Take all the numbers that are divisors of a.
  • Sum them.
  • Check if that sum is greater than a.

Thanks to @b2gills.

\$\endgroup\$
  • \$\begingroup\$ Every occurrence of $^a after the first one can be shortened to just $a. but it is even shorter if you write it as {$_ <sum grep $_%%*,^$_} Also looking at an earlier version, [+](LIST) works (no spaces) \$\endgroup\$ – Brad Gilbert b2gills Feb 21 '17 at 20:35
  • \$\begingroup\$ @BradGilbertb2gills Thanks! :) \$\endgroup\$ – Ven Feb 21 '17 at 22:22
1
\$\begingroup\$

><>, 47+3 46+3 39+3 = 42 bytes

:l)?!v}l:{:}$%0=*{
 v-$0<
l<+v?=1
)n;>0

Expects the input number to be present on the stack at program start, so +3 bytes for the -v flag. Try it online!

Edit: Golfed 1 byte from 3rd line: -\~0$ => -\:+

Edit 2: Near complete rewrite, previous version:

1v
}/!?)@:{:}+1r~?$r}:}%@:{:
-\:+
?\+l1=
;>0)n
\$\endgroup\$
1
\$\begingroup\$

JavaScript ES6, 61 50 bytes

a=>[...Array(a).keys()].reduce((b,c)=>a%c?b:b+c)>a

f=a=>[...Array(a).keys()].reduce((b,c)=>a%c?b:b+c)>a;

console.log(f(11));
console.log(f(12));
console.log(f(17));
console.log(f(18));

\$\endgroup\$
  • \$\begingroup\$ 45 bytes \$\endgroup\$ – Shaggy Sep 12 '17 at 15:51
2
\$\begingroup\$

Pyth, 11 bytes

>sPf!%QTS

Old:

L!%Qb>sPy#S

I can't use !% as a pfn for #, because it's two functions. Makes me sad :(.


L!%Qb>sPy#SQ    Program's argument: Q
L!%Qb           Define a lambda y, that takes b as an argument
 !%Qb           Return true if Q is divisible by b
          S     Make a range 1..Q
        y#      Filter that range with the lambda (y)
       P        Remove the last element (Q itself)
      s         Sum them
     >     Q    Check if that sum is greater than the program's argument
\$\endgroup\$
  • \$\begingroup\$ Not defining a function seems to be shorter: >sPf!%QTS \$\endgroup\$ – FryAmTheEggman Feb 21 '17 at 15:42
3
\$\begingroup\$

Japt, 9 7 6 bytes

<Uâ1 x

Saved 2 bytes thanks to ETHproductions. Saved 1 byte thanks to obarakon.

Try it online!

\$\endgroup\$
  • \$\begingroup\$ 9 characters, 10 bytes. \$\endgroup\$ – Metoniem Feb 21 '17 at 10:20
  • \$\begingroup\$ @Metoniem I'm sure â is 1 byte, in unicode at least (0xE2). \$\endgroup\$ – Tom Feb 21 '17 at 10:29
  • 1
    \$\begingroup\$ @Metoniem Japt uses the ISO-8859-1 encoding, in which â is a single byte. \$\endgroup\$ – ETHproductions Feb 21 '17 at 14:29
  • \$\begingroup\$ If â is given a truthy argument, it will remove the actual number from the remaining list, so you can do â1 x >U to save a couple bytes :-) \$\endgroup\$ – ETHproductions Feb 21 '17 at 14:30
  • \$\begingroup\$ @TomDevs Nice! You can do <Uâ1 x to save a byte. Japt adds the U in front of the program. \$\endgroup\$ – Oliver Feb 21 '17 at 16:12
1
\$\begingroup\$

Ruby, 39 32 bytes

->n{n<(1...n).sum{|x|n%x>0?0:x}}

Try it online!

Updated to Ruby 2.6

\$\endgroup\$
4
\$\begingroup\$

Powershell, 51 49 Bytes

param($i)((1..$i|?{!($i%$_)})-join"+"|iex)-gt2*$i

I wish I could remove some brackets.

-2 thanks to AdmBorkBork, instead of not counting the input in the initial range, we just take it into account in the final check.

Loop through range of 1.. to the $input, minus 1, find where (?) the inverse modulo of input by the current number is $true (aka only 0) - then -join all of those numbers together with + and iex the resulting string to calculate it, then see if the sum of these parts is greater than the input.

PS C:\++> 1..100 | ? {.\abundance.ps1 $_}
12
18
20
24
30
36
40
42
48
54
56
60
66
70
72
78
80
84
88
90
96
100
\$\endgroup\$
  • \$\begingroup\$ You can save two bytes by counting the top value and checking that it's bigger than 2x the input -- param($i)((1..$i|?{!($i%$_)})-join"+"|iex)-gt2*$i \$\endgroup\$ – AdmBorkBork Feb 21 '17 at 15:27
2
\$\begingroup\$

J, 19 bytes

Thanks to Conor O'Brien for cutting it to 19 bytes!

<[:+/i.#~i.e.]%2+i.

Previous: (34 bytes)

f=:3 :'(+/((i.y)e.y%2+i.y)#i.y)>y'

Returns 1 if it's abundant and 0 if it's not.

Output:

   f 3
0
   f 12
1
   f 11
0
   f 20
1
\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG! We allow anonymous functions, so you can remove the leading f=: as part of your byte count. Also, you can get down to 19 by converting to a tacit verb: <[:+/i.#~i.e.]%2+i. \$\endgroup\$ – Conor O'Brien Feb 22 '17 at 1:55
  • \$\begingroup\$ Thanks for the advice! However, could you please explain the cap verb ([:) and the switch verb (~). I don't really get what they're supposed to do in this tacit verb. \$\endgroup\$ – Blocks Feb 22 '17 at 11:06
  • \$\begingroup\$ ~ switches so it's i.e.#i. but what is the purpose of [: ? \$\endgroup\$ – Blocks Feb 22 '17 at 11:09
  • \$\begingroup\$ so you know about forks, right? (f g h) y' is the same as (f y) g (h y). When f` is a cap, ([: g h) y is roughly the same as g h y. As for ~, this switches the left and right arguments. It is important to know that ~ is not a verb but is actually an adverb. It modifies a verb. For example, we could have something like 2 %~ 8. Here, ~ modifies % to switch its arguments, so the expression is equivalent to 8 % 2. \$\endgroup\$ – Conor O'Brien Feb 22 '17 at 12:27
  • \$\begingroup\$ In the fork chain, #~ is evaluated after the verbs to its right are executed, so it's left argument becomes the result on the right \$\endgroup\$ – Conor O'Brien Feb 22 '17 at 12:28
0
\$\begingroup\$

Scala, 39 bytes

(n:Int)=>(1 until n filter{n%_<1}sum)>n
\$\endgroup\$
0
\$\begingroup\$

Javascript, 47 Bytes

a=>{s=d=0;while(a>d){s+=a%d?0:d;d++}return s>d}

f=a=>{s=d=0;while(a>d){s+=a%d?0:d;d++}return s>d};
console.log(f(11));
console.log(f(12));
console.log(f(15));
console.log(f(18));

Quite straight forward: check all numbers smaller than the input, if the input is divisible by them add them to the sum, and return whether the sum is bigger than the input

\$\endgroup\$
1
\$\begingroup\$

Haskell, 34 bytes

a n=n<sum[a|a<-[1..n-1],mod n a<1]

Try it online! Usage example: a 12 returns True.

\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES6), 33 bytes

let g =
x=>(f=n=>--n&&n*!(x%n)+f(n))(x)>x
<input type=number min=1 value=1 step=1 oninput="O.innerHTML=g(+value)"><br>
<pre id=O>false</pre>

\$\endgroup\$
  • \$\begingroup\$ I was sure a recursive answer would be best but I didn't think it would be this good. \$\endgroup\$ – Neil Feb 22 '17 at 0:18
2
\$\begingroup\$

Japt, 4 bytes

<âÔx

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.