# Am I not good enough for you?

### Background:

The current Perfect Numbers challenge is rather flawed and complicated, since it asks you to output in a complex format involving the factors of the number. This is a purely repost of the challenge.

## Challenge

Given a positive integer through any standard input format, distinguish between whether it is perfect or not.

A perfect number is a number that is equal to the sum of all its proper divisors (its positive divisors less than itself). For example, $$\6\$$ is a perfect number, since its divisors are $$\1,2,3\$$, which sum up to $$\6\$$, while $$\12\$$ is not a perfect number since its divisors ( $$\1,2,3,4,6\$$ ) sum up to $$\16\$$, not $$\12\$$.

### Test Cases:

Imperfect:
1,12,13,18,20,1000,33550335

Perfect:
6,28,496,8128,33550336,8589869056


### Rules

• Your program doesn't have to complete the larger test cases, if there's memory or time constraints, but it should be theoretically able to if it were given more memory/time.
• Output can be two distinct and consistent values through any allowed output format. If it isn't immediately obvious what represents Perfect/Imperfect, please make sure to specify in your answer.
• Wait, so truthy is for values that aren't perfect, and falsey is for values that are? – Esolanging Fruit Mar 12 '19 at 2:57
• @Tvde1 Proper divisors have to less than the number, otherwise no number other than 1 would be perfect, since every number is divisible by 1 and itself. The sum of proper divisors of 1 is 0 – Jo King Mar 12 '19 at 7:40
• @Grimy Only if you can prove so. Good luck! (though I'm wondering how that would save bytes) – Jo King Mar 12 '19 at 9:15
• So no, too bad. It would cut the size of an ECMA regex answer by a factor of about 3. – Grimmy Mar 12 '19 at 9:18
• "Output can be two distinct and consistent values" - may we not use "truthy vs falsey" here (e.g. for Python using zero vs non zero; a list with content vs an empty list; and combinations thereof)? – Jonathan Allan Mar 12 '19 at 10:15

# Bash, 56 bytes

Maybe a recursive function will be shorter? My Bash is certainly not strong.

s=0;for ((;v++<$1;)){$[s+=($1%$v<1)*$v-1];};[$s = \$1 ]


A full program taking a command line argument which has a return code 0 if it was perfect and 1 otherwise.

Try it online!

f x=x==sum[y|y<-[1..x-1],xmody<1]


Try it online!

# Twig, 108 bytes

Yeah, I managed to get something longer than Java :/

This creates a macro that you import into your own template and call the method a

{%macro a(n,x=0)%}{%if n>1%}{%for i in 1..n-1%}{%set x=x+i*(n%i==0)%}{%endfor%}{{x==n}}{%endif%}{%endmacro%}


Returns 1 for perfect numbers, nothing for imperfect.

You can try it on https://twigfiddle.com/0or03v (testcases included)

# Husk, 5 bytes

=¹ΣhḊ


Yields 1 for a perfect argument and 0 otherwise.

Try it online!

### How?

=¹ΣhḊ - Function: integer, n   e.g. 24
Ḋ - divisors                    [1,2,3,4,6,8,12,24]
h  - initial items               [1,2,3,4,6,8,12]
Σ   - sum                         36
¹    - first argument              24
=     - equal?                      0


# Actually, 5 bytes

;÷Σ½=


Full program taking input from STDIN which prints 1 for perfect numbers and 0 otherwise.

Try it online!

### How?

;÷Σ½= - full program, implicitly place input, n, onto the stack
;     - duplicate top of stack
÷    - divisors (including n)
Σ   - sum
½  - halve
= - equal?


# Factor, 57 bytes

: f ( x -- ? ) dup [1,b) [ dupd divisor? ] filter sum = ;


Try it online!

There is a shorter solution on the Rosetta Code that uses the divisors builtin:

: f ( n -- ? )  [ divisors sum ] [ 2 * ] bi = ;


but I wanted to come up with my own solution.

# Racket, 54 bytes

(require math)(define(p n)(=(sum(divisors n))(* 2 n)))


Try it online!

# Kotlin, 38 bytes

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


Expanded:

{ i -> (1..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
==i                compare to the original number
}               end lambda


Try it online!

# MathGolf, 5 4 bytes

─╡Σ=


Try it online!

## Explanation

─       get divisors (includes the number itself)
╡      discard from right of list (removes the number itself)
Σ     sum(list)
=    pop(a, b), push(a==b)


Since MathGolf returns divisors rather than proper divisors, the solution is 1 byte longer than it would have been in that case.

# Qbasic, 53 bytes

INPUT n
FOR i=1TO n-1
IF n\i=n/i THEN s=s+i
NEXT
?n=s


Literally quite Basic... Prints -1 for perfect numbers, 0 otherwise.

REPL

# APL(NARS), chars 11, bytes 22

{⍵=2÷⍨11π⍵}


11π return the sum of all divisors, test:

  f←{⍵=2÷⍨11π⍵}
f¨1 12 13 18 20 1000 33550335
0 0 0 0 0 0 0
f¨6 28 496 8128 33550336 8589869056
1 1 1 1 1 1


# MATL, 5 bytes

EGZ\s=


Try it out at MATL Online

Explanation

      % Implicitly grab the input as an integer
%    STACK: { 6 }
E     % Multiply by two
%    STACK: { 12 }
G     % Grab the input again
%    STACK: { 12,  6 }
Z\    % Compute all divisors (including itself)
%    STACK: { 12,  [1, 2, 3, 6] }
s     % Sum up these divisors
%    STACK: { 12, 12 }
=     % Check that the two elements on the stack are equal
%    STACK: { 1 }
% Implicitly display the result


# VDM-SL, 101 bytes

f(i)==s([x|x in set {1,...,i-1}&i mod x=0])=i;s:seq of nat+>nat
s(x)==if x=[]then 0 else hd x+s(tl x)


Summing in VDM is not built in, so I need to define a function to do this across the sequences, this ends up taking up the majority of bytes

A full program to run might look like this:

functions
f:nat+>bool
f(i)==s([x|x in set {1,...,i-1}&i mod x=0])=i;s:seq of nat+>nat
s(x)==if x=[]then 0 else hd x+s(tl x)


# Gaia, 4 bytes

dΣ⁻=


Try it online!

1 for perfect, 0 for imperfect.

d	| implicit input, n, push divisors
Σ	| take the sum
⁻	| subtract n
=	| equal to n?

# MACHINE LANGUAGE(X86, 32 bit), 38 bytes

00000788  53                push ebx
00000789  8B442408          mov eax,[esp+0x8]
0000078D  31DB              xor ebx,ebx
0000078F  31C9              xor ecx,ecx
00000791  43                inc ebx
00000792  39C3              cmp ebx,eax
00000794  730E              jnc 0x7a4
00000796  31D2              xor edx,edx
00000798  50                push eax
00000799  F7F3              div ebx
0000079B  58                pop eax
0000079C  09D2              or edx,edx
0000079E  75F1              jnz 0x791
000007A2  EBED              jmp short 0x791
000007A4  29C8              sub eax,ecx
000007A6  0F94C0            setz al
000007A9  0FB6C0            movzx eax,al
000007AC  5B                pop ebx
000007AE


Function lenght: 7AEh-788h=26h=38d; below assembly file that generate obj for linking:

; nasmw -fobj  this.asm
; bcc32 -v  file.c this.obj
section _DATA use32 public class=DATA
global _sumd
section _TEXT use32 public class=CODE

_sumd:
push    ebx
mov     eax,  dword[esp+  8]
xor     ebx,  ebx
xor     ecx,  ecx
.1:   inc     ebx
cmp     ebx,  eax
jae     .2
xor     edx,  edx
push    eax
div     ebx
pop     eax
or      edx,  edx
jnz     .1
jmp     short  .1
.2:   sub     eax,  ecx
setz    al
movzx   eax,  al
pop     ebx
ret


below the C file for link and test that function:

#include <stdio.h>
unsigned es[]={1,12,13,18,20,1000,33550335,6,28,496,8128,33550336,0};
int sumd(unsigned);

main(void)
{int  i;
for(i=0;es[i];++i)
printf("f(%u)=%u\n",es[i],sumd(es[i]));
return 0;
}


below the macro assembly file source of the .asm one:

; nasmw -fobj  this.asm
; bcc32 -v  file.c this.obj
section _DATA use32 public class=DATA
global  _sumd
section _TEXT use32 public class=CODE

_sumd:
<b  |a=^8|b^=b|c^=c
.1:  ++b |b>=a#.2|r^=r|<a|div b|>a|r|=r|jnz .1|c+=b|#.1
.2:  a-=c|setz al|movzx eax, al
>b
ret


below the 113 bytes golfing code of above:

_sumd:<b|a=^8|b^=b|c^=c|.1:++b|b>=a#.2|r^=r|<a|div b|>a|r|=r|jnz .1|c+=b|#.1|.2:a-=c|setz al|movzx eax, al|>b|ret


the results:

f(1)=0
f(12)=0
f(13)=0
f(18)=0
f(20)=0
f(1000)=0
f(33550335)=0
f(6)=1
f(28)=1
f(496)=1
f(8128)=1
f(33550336)=1


I got the trick of use push eax|div | pop eax from https://codegolf.stackexchange.com/a/181515/58988