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

2
\$\begingroup\$

Japt, 4 bytes

<âÔx

Try it online!

\$\endgroup\$
2
\$\begingroup\$

C# (Visual C# Interactive Compiler), 48 bytes

x=>Enumerable.Range(1,x).Sum(y=>y<x&x%y<1?y:0)>x

Try it online!

Above is a LINQ based solution that creates a range of numbers slightly larger than the input number. Each element is tested for being a) being a proper divisor of the input and b) being less than the input. If both checks pass, it is added to a sum which is compared to the input.

Below is a a recursive solution that uses an inner function to calculate the summation. While this one seems the most interesting to me, I think the LINQ based approach will not be beat.

C# (Visual C# Interactive Compiler), 60 bytes

x=>{int g(int y)=>(x%y<1?y:0)+(++y<x?g(y):0);return g(1)>x;}

Try it online!

Finally, we have an iterative solution which currently is between the LINQ based approach and the recursive one.

C# (Visual C# Interactive Compiler), 53 bytes

x=>{int y=0,z=0;for(;++y<x;z+=x%y<1?y:0);return z>x;}

Try it online!

\$\endgroup\$
2
+100
\$\begingroup\$

APL (Dyalog Unicode), 11 bytesSBCS

-2 bytes thanks to @Adám

⊢<1⊥∘⍸0=⍳|⊢

Try it online!

Explanation:

⊢<1⊥∘⍸0=⍳|⊢ ⍝ Monadic function train
        ⍳   ⍝ Generate integers from 1 to input
        |⊢ ⍝ For each of the above, modulo the input    
      0=   ⍝ Return a boolean vector where ones correspond
           ⍝ to zeroes
     ⍸      ⍝ Return the indices of the ones in the above vector
           ⍝ This results in a vector of the proper divisors of our input
  1⊥∘      ⍝ Composed with the above, decode into unary base.
           ⍝ This has the same effect as summing the vector, but is used
           ⍝ here to comply with the function train format.
⊢<         ⍝ Is the above sum greater than our input?
\$\endgroup\$
2
\$\begingroup\$

R, 32 28 bytes

2*(n=scan())<(x=1:n)%*%!n%%x

Try it online!

Reads n from stdin, returns TRUE for abundant numbers and FALSE otherwise.

\$\endgroup\$
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\$

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\$
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
1
\$\begingroup\$

Pyth, 8 bytes

>s{*MPyP

Try it online here.

>s{*MPyPQQ   Implicit: Q=eval(input())
             Trailing QQ inferred
       PQ    Prime factors of Q
      y      Take the powerset of the above
     P       Discard the last one (i.e. the original set itself)
   *M        Take the product of each list
  {          Deduplicate
 s           Take the sum
>        Q   Is the above greater than Q? Implicit print
\$\endgroup\$
1
\$\begingroup\$

PHP, 63 bytes

function a($x){for($i=1;$i<$x;$i++){$s+=$x%$i?0:$i;}echo$s>$x;}

Usage: a(12);

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

APL(NARS) 11 chars, 22 bytes

{⍵<2÷⍨11π⍵}

11π is the function sum divisor, so sum proper divisor would be: {(-⍵)+11π⍵}; test:

  f←{⍵<2÷⍨11π⍵}
  {1=f ⍵:⍵⋄⍬}¨1..100
12  18  20  24  30  36  40  42  48  54  56  60  66  70  72  78  80  84  88  90  96  100 
\$\endgroup\$
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\$
1
\$\begingroup\$

Forth (gforth), 45 bytes

: f 0 over 1 ?do over i mod 0= i * - loop < ;

Try it online!

Explanation

Loops over every number from 1 to n-1, summing all values that divide n perfectly. Returns true if sum is greater than n

Code Explanation

: f                \ start word definition
  0 over 1         \ create a value to hold the sum and setup up the bounds of the loop
  ?do              \ start a counted loop from 1 to n. (?do skips if start = end)
    over           \ copy n to the top of the stack
    i mod 0=       \ check if i divides n perfectly
    i * -          \ if so, use the fact that -1 = true in forth to add i to the sum
  loop             \ end the counted loop
  <                \ check if n is less than the sum
;                  \ end the word definition
\$\endgroup\$
1
\$\begingroup\$

C# (.NET Core), 59, 53 bytes

Without LINQ.

EDIT: Thanks to ASCII-only for pointing out for(;++k<p;) instead of for(;k<p;k++).

C# (.NET Core), 53 bytes

p=>{int k=0,n=0;for(;++k<p;)n+=p%k<1?k:0;return n>p;}

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ 53 \$\endgroup\$ – ASCII-only Mar 13 at 5:56
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\$
0
\$\begingroup\$

C, 68 bytes

int s,x;main(i){scanf("%d",&x);while(++i<x)s+=x%i^0?0:i;return s>x;}
\$\endgroup\$
  • 3
    \$\begingroup\$ Welcome to the site! I think you could save some bytes by taking input from function arguments, rather than implementing main with scanf. For example int f(int s,int x){while(++i<x)s+=x%i^0?0:i;return s>x;} Also, I'm not an expert at C golfing, but I think some compilers default to int functions with int arguments, so you could do f(s,x){while(++i<x)s+=x%i^0?0:i;return s>x;}, but you'd have to find the right compiler and test it first. \$\endgroup\$ – DJMcMayhem Feb 21 '17 at 17:59
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
0
\$\begingroup\$

Racket, 46 bytes

That's 46 bytes including the (require math).

(λ(n)(>(-(sum(divisors n))n)n))

The function produces booleans.

Try it online!

It's pretty simple, uses the divisors function to produce a list of all divisors of n. Since the list includes n itself, we need to remove it after summing.

\$\endgroup\$
  • \$\begingroup\$ Hello and welcome to PPCG. Nice first post; however, I would think that you ought to include the byte count for your (require math) import. \$\endgroup\$ – Jonathan Frech Jan 23 at 21:45
  • \$\begingroup\$ Sorry! I was unsure about what exactly to add to the byte count. \$\endgroup\$ – waf9000 Jan 23 at 22:20
  • \$\begingroup\$ No problem. Usually, one counts everything the function or program truly needs -- excluding boiler code only written for testing. However, on edge cases one sometimes has to resort to the current consensus -- written and talked about on meta. In practice, you will often be notified by comment if someone disagrees with your byte count. \$\endgroup\$ – Jonathan Frech Jan 23 at 22:25
0
\$\begingroup\$

8086 Assembly edited from 179016, 21 bytes

f:      mov cx, ax
        mov bx, ax
        dec cx
.a:     xor dx, dx
        push ax
        div cx
        pop ax
        test dx, dx
        jnz .b
        sub bx, cx
        jc .c
.b:     loop .a
.c:    

Saved from the reverse working

\$\endgroup\$
0
\$\begingroup\$

Java 8, 66 bytes

n->java.util.stream.IntStream.range(1,n).filter(i->n%i==0).sum()>n

Try it online!

Explanation

n->                                       // define a lambda function
    java.util.stream.IntStream.range(1,n) // create a stream of integers from 1 to n
    .filter(i->n%i==0)                    // filter out non-factors
    .sum()                                // sum the factors
>n                                        // compare the sum to the original number n
                                          // implicit return

Edit: Looks like someone already did this 2 years ago and got 1 byte shorter

\$\endgroup\$
0
\$\begingroup\$

Javascript,72bytes

var n=prompt(),div=0,i=1;while(++i<=n/2){div+=n%i?0:i}console.log(div>n)
\$\endgroup\$
  • \$\begingroup\$ As @SriotchilismO'Zaic points out, this appears to be a snippet which is not compliant with our current I/O consensus. Please fix your post accordingly. \$\endgroup\$ – Jonathan Frech Mar 13 at 8:32
  • \$\begingroup\$ As @JonathanFrech specified, modified the changes and further refined the code. \$\endgroup\$ – Jeyanth Mar 13 at 9:58
0
\$\begingroup\$

Kotlin, 37 bytes

{i->(2..i-1).filter{i%it==0}.sum()>i}

Expanded:

{ i -> (2..i - 1).filter { i % it == 0 }.sum() > i }

Explanation:

  {i->                      start lambda with parameter i
    (2..i-1)                create a range from 2 until i - 1 (potential divisors)
      .filter{i%it==0}      it's a divisor if remainder = 0; filter divisors
        .sum()              add all divisors
          >i                compare to the original number

Try it online!

\$\endgroup\$
0
\$\begingroup\$

TI-BASIC (TI-84), 23 bytes

:2Ans<sum(seq(Ans/Xnot(remainder(Ans,X)),X,1,Ans,1

This answer is very similar to my answer here.
Input is in Ans.
Output is in Ans and is automatically printed out when the program completes.

Explanation:
(TI-BASIC doesn't have comments, so just assume that ; makes a comment)

:2Ans=sum(seq(Ans/Xnot(remainder(Ans,X)),X,1,Ans    ;Full program

 2Ans                                               ;double the input
          seq(                                      ;generate a list
                                         X,          ;using the variable X,
                                           1,        ;starting at 1,
                                             Ans     ;and ending at the input
                                                     ;with an implied increment of 1
              Ans/X                                 ;from the input divided by X
                   not(                ),           ;multiplied by the negated result of
                       remainder(Ans,X)              ;the input modulo X
                                                     ;(result: 0 or 1)
      sum(                                          ;sum up the elements in the list
     <                                              ;is the sum greater than double the input?

Example:

12
           12
prgmCDGF4
            1
6
            6
prgmCDGF4
            0

Note: The byte count of a program is evaluated using the value in [MEM]>[2]>[7] (36 bytes) then subtracting the length of the program's name, CDGF2, (5 bytes) and an extra 8 bytes used for storing the program:

36 - 5 - 8 = 23 bytes

\$\endgroup\$
  • \$\begingroup\$ I counted 50 characters, so presumably 50 bytes... what am I missing? \$\endgroup\$ – Adam Mar 13 at 14:33
  • \$\begingroup\$ @Adam all of the functions in TI-BASIC are 1-byte tokens. Therefore, sum(, seq(, remainder(, and not( would all be considered as 1 byte each. Ans is also a 1-byte token. \$\endgroup\$ – Tau Mar 13 at 14:40
  • \$\begingroup\$ Ah, okay. I see now \$\endgroup\$ – Adam Mar 13 at 14:42
  • \$\begingroup\$ Actually, I should clarify that the remainder( function is a 2-byte token, not 1-byte. \$\endgroup\$ – Tau Mar 13 at 16:23
0
\$\begingroup\$

tinylisp, 78 bytes

(load library
(q((N)(l N(sum(filter(partial divides?(q D)(list(q _)N))(range N

Try it online!

Start with a list of each D from 0 through N - 1; filter it for the values of D that exactly divide N. Sum the results. Iff N is less than that sum, N is abundant.

\$\endgroup\$
0
\$\begingroup\$

TI-BASIC, 21 bytes

seq(I,I,1,A-1
A<sum(Ansnot(fpart(A/Ans

TI-BASIC usually has a builtin for this kind of thing, but nothing fits that well here. Takes input from the A variable and outputs 1 or 0 if the number is or isn't abundant.

seq( generates a list of numbers from a function. Here it executes the function I on the I variable from one to one less than the input. Then working backward from the next line, we divide our input by the list we generated (stored in Ans) and take the fractional part so we have a new list of remainders for each potential divisor. We then build a list of booleans by taking not( on the remainder list and multiply that by the original list in Ans implicitly to get a list of proper divisors. Then we just sum the list of proper divisors and compare that to the input.

This was 24 bytes, golfed down to 21 using not( instead of *(0=

\$\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.