Am I not good enough for you?

29

1

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.

Jo King

Posted 2019-03-12T02:41:31.763

Reputation: 38 234

Wait, so truthy is for values that aren't perfect, and falsey is for values that are? – Esolanging Fruit – 2019-03-12T02:57:14.250

@EsolangingFruit Yes, though the actual output values don't really matter, so you can output true for perfect numbers if you wish – Jo King – 2019-03-12T02:58:53.190

Fair enough, but wording the challenge as "output whether it is not perfect" makes the test cases slightly confusing if you interpret "truthy" as meaning "values corresponding to true". – Esolanging Fruit – 2019-03-12T03:00:27.433

@EsolangingFruit Good point. I've renamed the test cases to Imperfect/Perfect to make it clearer – Jo King – 2019-03-12T03:01:56.383

Why is 1 not a perfect number? 1 == 1. – Tvde1 – 2019-03-12T07:36:16.403

2@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 – 2019-03-12T07:40:21.070

Are we allowed to assume there are no odd perfect numbers? – Grimmy – 2019-03-12T08:56:01.450

3

@Grimy Only if you can prove so. Good luck! (though I'm wondering how that would save bytes)

– Jo King – 2019-03-12T09:15:51.690

1So no, too bad. It would cut the size of an ECMA regex answer by a factor of about 3. – Grimmy – 2019-03-12T09:18:10.540

3"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 – 2019-03-12T10:15:22.617

Answers

16

Brachylog, 4 bytes

fk+?

Try it online!

The predicate succeeds for perfect inputs and fails for imperfect inputs, printing true. or false. if run as a complete program (except on the last test case which takes more than a minute on TIO).

        The input's
f       factors
 k      without the last element
  +     sum to
   ?    the input.

Unrelated String

Posted 2019-03-12T02:41:31.763

Reputation: 5 300

1I like how the code says fk :x – Ismael Miguel – 2019-03-13T01:38:16.053

9

Neim, 3 bytes


Try it online!

(I don't actually know how to run all of the test cases at once, since I started learning Neim about fifteen minutes ago, but I did check them individually.)

Prints 0 for imperfect, 1 for perfect.

      Pop an int from the stack and push its proper divisors,
       implicitly reading the int from a line of input as the otherwise absent top of the stack.
      Pop a list from the stack and push the sum of the values it contains.
      Pop two ints from the stack and push 1 if they are equal, 0 if they are not;
       implicitly reading the same line of input that was already read as the second int, I guess?
       Implicitly print the contents of the stack, or something like that.

Unrelated String

Posted 2019-03-12T02:41:31.763

Reputation: 5 300

2"I guess?"; "or something like that.". When you're not even sure what you've written yourself, haha. ;) But yes, that's indeed how it works. I don't know Neim, but using the input implicitly like that and outputting implicitly at the end implicitly, is similar in 05AB1E. – Kevin Cruijssen – 2019-03-13T12:26:45.370

How is `` 1 byte? Does Neim use only 128 such non-standart characters? – kajacx – 2019-03-13T13:39:06.347

3

@kajacx Neim has its own code page. Therefore, each of the 256 characters present in the codepage can be encoded using 1 byte.

– Mr. Xcoder – 2019-03-13T17:23:26.167

8

R, 33 29 bytes

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

Try it online!

Returns TRUE for perfect numbers and FALSE for imperfect ones.

Giuseppe

Posted 2019-03-12T02:41:31.763

Reputation: 21 077

What do the 2 !s in a row get you? – CT Hall – 2019-03-12T03:16:45.890

@CTHall I misread the spec; they originally mapped 0 (perfect) to FALSE and nonzero to TRUE but I removed one of them to reverse the mapping. It's a useful golfing trick to cast from numeric to logical, often in conjunction with which or [. – Giuseppe – 2019-03-12T03:37:42.267

7

Japt -!, 4 bytes

¥â¬x
-----------------
            Implicit Input U
¥           Equal to
   x        Sum of
 â          Factors of U
  ¬         Without itself

For some reason ¦ doesnt work on tio so I need to use the -! flag and ¥ instead

Try it online!

Luis felipe De jesus Munoz

Posted 2019-03-12T02:41:31.763

Reputation: 9 639

That's not a TIO issue; U doesn't get auto-inserted before !. – Shaggy – 2019-03-12T09:31:44.257

7

Jelly, 3 bytes

Æṣ=

Try it online!

Mr. Xcoder

Posted 2019-03-12T02:41:31.763

Reputation: 39 774

6

Python 3, 46 bytes

lambda x:sum(i for i in range(1,x)if x%i<1)==x

Try it online!

Brute force, sums the factors and checks for equality.

Neil A.

Posted 2019-03-12T02:41:31.763

Reputation: 2 038

2Using the comprehension condition as a mask for your iteration variable would save a byte. – Jonathan Frech – 2019-03-12T04:04:04.933

Since you can return truthy for an imperfect number, lambda x:sum(i for i in range(1,x)if x%i<1)^x should work as well. – nedla2004 – 2019-03-12T13:13:20.237

5

Octave, 25 bytes

@(n)~mod(n,t=1:n)*t'==2*n

Try it online!

Explanation

@(n)~mod(n,t=1:n)*t'==2*n

@(n)                        % Define anonymous function with input n
             1:n            % Row vector [1,2,...,n]
           t=               % Store in variable t
     mod(n,     )           % n modulo [1,2,...,n], element-wise. Gives 0 for divisors
    ~                       % Logical negate. Gives 1 for divisors
                  t'        % t transposed. Gives column vector [1;2;...;n]
                 *          % Matrix multiply
                      2*n   % Input times 2
                    ==      % Equal? This is the output value

Luis Mendo

Posted 2019-03-12T02:41:31.763

Reputation: 87 464

5

Python, 45 bytes

lambda n:sum(d*(n%d<1)for d in range(1,n))==n

True for perfect; False for others (switch this with == -> !=)

Try it online!

 44 42  41 bytes (-2 thanks to ovs) if we may output using "truthy vs falsey":

f=lambda n,i=1:i/n or-~f(n,i+1)-(n%i<1)*i

(falsey (0)) for perfect; truthy (a non-zero integer) otherwise

Jonathan Allan

Posted 2019-03-12T02:41:31.763

Reputation: 67 804

If the second output format is valid, this can be done in 42 bytes.

– ovs – 2019-03-12T11:43:39.173

@ovs ah, nicely done. – Jonathan Allan – 2019-03-12T12:06:24.870

@ovs ..and another saved from that - thanks! – Jonathan Allan – 2019-03-12T12:16:16.880

4

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

n=>Enumerable.Range(1,n).Sum(x=>n%x<1?x:0)^n*2

Returns 0 if perfect, otherwise returns a positive number. I don't know if outputting different types of integers are allowed in place of two distinct truthy and falsy values, and couldn't find any discussion on meta about it. If this is invalid, I will remove it.

Try it online!

C# (Visual C# Interactive Compiler), 49 47 bytes

n=>Enumerable.Range(1,n).Sum(x=>n%x<1?x:0)==n*2

Try it online!

Embodiment of Ignorance

Posted 2019-03-12T02:41:31.763

Reputation: 7 014

4

JavaScript, 38 bytes

n=>eval("for(i=s=n;i--;)n%i||!(s-=i)")

Try it online!

(Last testcase timeout on TIO.)

tsh

Posted 2019-03-12T02:41:31.763

Reputation: 13 072

@Arnauld Just forgot to remove the f= after converting from a recursive function. – tsh – 2019-03-12T10:07:24.313

Just out of curiosity, why not going with a recursive version? (It would be 34 bytes.) – Arnauld – 2019-03-12T10:09:39.793

@Arnauld because recursive version would simply failed for larger testcase due to stack overflow. Maybe I need some environments default to strict mode to make it work. – tsh – 2019-03-12T10:17:27.047

2Fair enough, but your program doesn't have to complete the larger test cases (which I think is the default rule, anyway). – Arnauld – 2019-03-12T10:22:50.177

3

Ruby, 33 bytes

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

Try it online!

Kirill L.

Posted 2019-03-12T02:41:31.763

Reputation: 6 693

3

Java (JDK), 54 bytes

n->{int s=0,d=0;for(;++d<n;)s+=n%d<1?d:0;return s==n;}

Try it online!

Though for a strict number by number matching, the following will return the same values, but is only 40 bytes.

n->n==6|n==28|n==496|n==8128|n==33550336

Try it online!

Olivier Grégoire

Posted 2019-03-12T02:41:31.763

Reputation: 10 647

The rules say 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. – Jo King – 2019-03-13T14:28:09.387

@JoKing Does that mean that I can't use a Java int at all, but rather a BigInteger? Because Java has BigIntegers, but it won't ever have an int that's more than 31 bits as signed, which can't hold any other value than those represented here... – Olivier Grégoire – 2019-03-13T14:30:23.857

no, but if the program should still work if the int type was unbounded – Jo King – 2019-03-13T21:16:42.260

1@JoKing Ok, I switched the two solutions again to have the computation first. – Olivier Grégoire – 2019-03-13T22:35:31.780

3

TI-BASIC (TI-84), 30 23 bytes

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

Horribly inefficient, but it works.
Reducing the bytecount sped up the program by a lot.
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
     =                                              ;equal?

Example:

6
            6
prgmCDGF2
            1
7
            7
prgmCDGF2
            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

Tau

Posted 2019-03-12T02:41:31.763

Reputation: 1 935

3

x86 Assembly, 45 43 Bytes.

6A 00 31 C9 31 D2 41 39  C1 7D 0B 50 F7 F9 58 85
D2 75 F1 51 EB EE 31 D2  59 01 CA 85 C9 75 F9 39
D0 75 05 31 C0 40 EB 02  31 C0 C3

Explaination (Intel Syntax):

PUSH $0          ; Terminator for later
XOR ECX, ECX        ; Clear ECX
.factor:
    XOR EDX, EDX    ; Clear EDX
    INC ECX
    CMP ECX, EAX    ; divisor >= input number?
    JGE .factordone ; if so, exit loop.
    PUSH EAX        ; backup EAX
    IDIV ECX        ; divide EDX:EAX by ECX, store result in EAX and remainder in EDX
    POP EAX         ; restore EAX
    TEST EDX, EDX   ; remainder == 0?
    JNZ .factor     ; if not, jump back to loop start
    PUSH ECX        ; push factor
    JMP .factor     ; jump back to loop start
.factordone:
XOR EDX, EDX        ; clear EDX
.sum:
    POP ECX         ; pop divisor
    ADD EDX, ECX    ; sum into EDX
    TEST ECX, ECX   ; divisor == 0?
    JNZ .sum        ; if not, loop.
CMP EAX, EDX        ; input number == sum?
JNE .noteq          ; if not, skip to .noteq
    XOR EAX, EAX    ; clear EAX
    INC EAX         ; increment EAX (sets to 1)
JMP .return         ; skip to .return
.noteq:
    XOR EAX, EAX    ; clear EAX
.return:
RETN

Input should be provided in EAX.
Function sets EAX to 1 for perfect and to 0 for imperfect.

EDIT: Reduced Byte-Count by two by replacing MOV EAX, $1 with XOR EAX, EAX and INC EAX

Fayti1703

Posted 2019-03-12T02:41:31.763

Reputation: 71

1I use a macro assembly so I don't know for sure but the comment"; divisor > input number" for me would be "; divisor >= input number" – RosLuP – 2019-03-14T16:54:36.147

Assembly has easy operations one could reduce instructions length puts all in a line, use indentation and comment every 10 20 asm instructions.... – RosLuP – 2019-03-14T16:58:37.110

@RosLuP I've fixed the comment in the code (thanks), but I don't know what you mean with your second comment. – Fayti1703 – 2019-03-14T19:23:48.657

3

Labyrinth, 80 bytes

?::`}:("(!@
perfect:
{:{:;%"}
+puts; "
}zero: "
}else{(:
"negI"  _~
""""""{{{"!@

The Latin characters perfect puts zero else neg I are actually just comments*.
i.e. if the input is perfect a 0 is printed, otherwise -1 is.

Try it online!


* so this or this work too...

?::`}:("(!@               ?::`}:("(!@
       :                  BEWARE :
{:{:;%"}                  {:{:;%"}
+    ; "                  +LAIR; "
}    : "                  } OF : "
}    {(:                  }MINO{(:
"    "  _~                "TAUR"  _~
""""""{{{"!@              """"""{{{"!@

How?

Takes as an input a positive integer n and places an accumulator variable of -n onto the auxiliary stack, then performs a divisibility test for each integer from n-1 down to, and including, 1, adding any which do divide n to the accumulator. Once this is complete if the accumulator variable is non-zero a -1 is output, otherwise a 0 is.

The ?::`}:( is only executed once, at the beginning of execution:

?::`}:(                                                      Main,Aux
?       - take an integer from STDIN and place it onto Main  [[n],[]]
 :      - duplicate top of Main                            [[n,n],[]]
  :     - duplicate top of Main                          [[n,n,n],[]]
   `    - negate top of Main                            [[n,n,-n],[]]
    }   - place top of Main onto Aux                       [[n,n],[-n]]
     :  - duplicate top of Main                          [[n,n,n],[-n]]
      ( - decrement top of Main                        [[n,n,n-1],[-n]]

The next instruction, ", is a no-op, but we have three neighbouring instructions so we branch according to the value at the top of Main, zero takes us forward, while non-zero takes us right.

If the input was 1 we go forward because the top of Main is zero:

(!@                                                          Main,Aux
(   - decrement top of Main                             [[1,1,-1],[-1]]
 !  - print top of Main, a -1
  @ - exit the labyrinth

But if the input was greater than 1 we turn right because the top of Main is non-zero:

:}                                                           Main,Aux
:  - duplicate top of Main                         [[n,n,n-1,n-1],[-n]]
 } - place top of Main onto Aux                        [[n,n,n-1],[-n,n-1]]

At this point we have a three-neighbour branch, but we know n-1 is non-zero, so we turn right...

"%                                                           Main,Aux
"  - no-op                                             [[n,n,n-1],[-n,n-1]]
 % - place modulo result onto Main                   [[n,n%(n-1)],[-n,n-1]]
   - ...i.e we've got our first divisibility indicator n%(n-1), an
   -    accumulator, a=-n, and our potential divisor p=n-1:
   -                                                 [[n,n%(n-1)],[a,p]]

We are now at another three-neighbour branch at %.

If the result of % was non-zero we go left to decrement our potential divisor, p=p-1, and leave the accumulator, a, as it is:

;:{(:""}"                                                    Main,Aux
;          - drop top of Main                                [[n],[a,p]]
 :         - duplicate top of Main                         [[n,n],[a,p]]
  {        - place top of Aux onto Main                  [[n,n,p],[a]]
           - three-neighbour branch but n-1 is non-zero so we turn left
   (       - decrement top of Main                     [[n,n,p-1],[a]]
    :      - duplicate top of Main                 [[n,n,p-1,p-1],[a]]
     ""    - no-ops                                [[n,n,p-1,p-1],[a]]
       }   - place top of Main onto Aux                [[n,n,p-1],[a,p-1]]
        "  - no-op                                     [[n,n,p-1],[a,p-1]]
         % - place modulo result onto Main           [[n,n%(p-1)],[a,p-1]]
           - ...and we branch again according to the divisibility
           -    of n by our new potential divisor, p-1

...but if the result of % was zero (for the first pass only when n=2) we go straight on to BOTH add the divisor to our accumulator, a=a+p, AND decrement our potential divisor, p=p-1:

;:{:{+}}""""""""{(:""}                                       Main,Aux
;                      - drop top of Main                    [[n],[a,p]]
 :                     - duplicate top of Main             [[n,n],[a,p]]
  {                    - place top of Aux onto Main      [[n,n,p],[a]]
   :                   - duplicate top of Main         [[n,n,p,p],[a]]
    {                  - place top of Aux onto Main  [[n,n,p,p,a],[]]
     +                 - perform addition            [[n,n,p,a+p],[]]
      }                - place top of Main onto Aux      [[n,n,p],[a+p]]
       }               - place top of Main onto Aux        [[n,n],[a+p,p]]
        """""""        - no-ops                            [[n,n],[a+p,p]]
                       - a branch, but n is non-zero so we turn left
               "       - no-op                             [[n,n],[a+p,p]]
                {      - place top of Aux onto Main      [[n,n,p],[a+p]]
                       - we branch, but p is non-zero so we turn right
                 (     - decrement top of Main         [[n,n,p-1],[a+p]]
                  :    - duplicate top of Main     [[n,n,p-1,p-1],[a+p]]
                   ""  - no-ops                    [[n,n,p-1,p-1],[a+p]]
                     } - place top of Main onto Aux    [[n,n,p-1],[a+p,p-1]]

At this point if p-1 is still non-zero we turn left:

"%                                                           Main,Aux
"  - no-op                                             [[n,n,p-1],[a+p,p-1]]
 % - modulo                                          [[n,n%(p-1)],[a+p,p-1]]
   - ...and we branch again according to the divisibility
   -    of n by our new potential divisor, p-1

...but if p-1 hit zero we go straight up to the : on the second line of the labyrinth (you've seen all the instructions before, so I'm leaving their descriptions out and just giving their effect):

:":}"":({):""}"%;:{:{+}}"""""""{{{                           Main,Aux
:                                  -                   [[n,n,0,0],[a,0]]
 "                                 -                   [[n,n,0,0],[a,0]]
                                   - top of Main is zero so we go straight
                                   -  ...but we hit the wall and so turn around
  :                                -                 [[n,n,0,0,0],[a,0]]
   }                               -                   [[n,n,0,0],[a,0,0]]
                                   - top of Main is zero so we go straight
    ""                             -                   [[n,n,0,0],[a,0,0]]
      :                            -                 [[n,n,0,0,0],[a,0,0]]
       (                           -                [[n,n,0,0,-1],[a,0,0]]
        {                          -              [[n,n,0,0,-1,0],[a,0]]
                                   - top of Main is zero so we go straight
                                   -  ...but we hit the wall and so turn around
         (                         -             [[n,n,0,0,-1,-1],[a,0]]
          :                        -          [[n,n,0,0,-1,-1,-1],[a,0]]
           ""                      -          [[n,n,0,0,-1,-1,-1],[a,0]]
             }                     -             [[n,n,0,0,-1,-1],[a,0,-1]]
                                   - top of Main is non-zero so we turn left
              "                    -             [[n,n,0,0,-1,-1],[a,0,-1]]
               %                   - (-1)%(-1)=0     [[n,n,0,0,0],[a,0,-1]]
                ;                  -                   [[n,n,0,0],[a,0,-1]]
                 :                 -                 [[n,n,0,0,0],[a,0,-1]]
                  {                -              [[n,n,0,0,0,-1],[a,0]]
                   :               -           [[n,n,0,0,0,-1,-1],[a,0]]
                    {              -         [[n,n,0,0,0,-1,-1,0],[a]]
                     +             -           [[n,n,0,0,0,-1,-1],[a]]
                      }            -              [[n,n,0,0,0,-1],[a,-1]]
                       }           -                 [[n,n,0,0,0],[a,-1,-1]]
                        """""""    -                 [[n,n,0,0,0],[a,-1,-1]]
                                   - top of Main is zero so we go straight
                               {   -              [[n,n,0,0,0,-1],[a,-1]]
                                {  -           [[n,n,0,0,0,-1,-1],[a]]
                                 { -         [[n,n,0,0,0,-1,-1,a],[]]

Now this { has three neighbouring instructions, so...

...if a is zero, which it will be for perfect n, then we go straight:

"!@                                                          Main,Aux
"   -                                        [[n,n,0,0,0,-1,-1,a],[]]
    - top of Main is a, which is zero, so we go straight
 !  - print top of Main, which is a, which is a 0
  @ - exit the labyrinth

...if a is non-zero, which it will be for non-perfect n, then we turn left:

_~"!@                                                        Main,Aux
_     - place a zero onto Main             [[n,n,0,0,0,-1,-1,a,0],[]]
 ~    - bitwise NOT top of Main (=-1-x)   [[n,n,0,0,0,-1,-1,a,-1],[]]
  "   -                                   [[n,n,0,0,0,-1,-1,a,-1],[]]
      - top of Main is NEGATIVE so we turn left
   !  - print top of Main, which is -1
    @ - exit the labyrinth

Jonathan Allan

Posted 2019-03-12T02:41:31.763

Reputation: 67 804

2

Javascript, 62

n=>n==[...Array(n).keys()].filter(a=>n%a<1).reduce((a,b)=>a+b)

Explanation (although it's pretty simple)

n=> //return function that takes n
  n== //and returns if n is equal to
    [...Array(n).keys()] //an array [0..(n-1)]...
      .filter(a=>n%a<1) //where all of the elements that are not divisors of n are taken out...
      .reduce((a,b)=>a+b) //summed up

Thanks to Jo King for the improvement!

vityavv

Posted 2019-03-12T02:41:31.763

Reputation: 734

2

CJam, 17 bytes

ri_,(;{1$\%!},:+=

Try it online!

Esolanging Fruit

Posted 2019-03-12T02:41:31.763

Reputation: 13 542

2

05AB1E, 4 bytes

ѨOQ

Try it online!

Explanation

  O    # the sum
Ñ      # of the divisors of the input
 ¨     # with the last one removed
   Q   # equals the input

Emigna

Posted 2019-03-12T02:41:31.763

Reputation: 50 798

2

Pyth, 9 13 bytes

qsf!%QTSt

Try it online!

Thank you to the commentors for the golf help

Finds all the factors of the input, sums them, and compares that to the original input.

JPeroutek

Posted 2019-03-12T02:41:31.763

Reputation: 734

A few golfs for you - q0 can be replaced with !, and SQ produces the range [1-Q], so the range [1-Q) can be generated using StQ. As the Qs are now at the end of the program they can both be omitted. Fettled version, 9 bytes - qsf!%QTSt

– Sok – 2019-03-12T10:35:38.213

2

C (gcc), 41 bytes

f(n,i,s){for(i=s=n;--i;s-=n%i?0:i);n=!s;}

Try it online!

1: 0
12: 0
13: 0
18: 0
20: 0
1000: 0
33550335: 0
6: 1
28: 1
496: 1
8128: 1
33550336: 1
-65536: 0 <---- Unable to represent final test case with four bytes, fails

Let me know if that failure for the final case is an issue.

Marcos

Posted 2019-03-12T02:41:31.763

Reputation: 171

141 bytes – tsh – 2019-03-12T09:00:06.857

2"Output can be two distinct and consistent values through any allowed output format." You're not returning any two distinct values. – Olivier Grégoire – 2019-03-12T09:29:08.140

2@OlivierGrégoire Fortunately that can be readily fixed by replacing the space with an exclamation mark! – Neil – 2019-03-12T09:33:37.960

1@Neil Better yet, it can be fixed with n=!s; instead of return!s; to save 5 bytes. – None – 2019-03-12T09:50:07.953

@OlivierGrégoire ahh, I forgot that point. Also, updated the with the improved code. I tried something similar, but the idiot I am I did s=s which more than likely got optimized out. – Marcos – 2019-03-13T00:26:56.987

2

Powershell, 46 bytes 43 bytes

param($i)1..$i|%{$o+=$_*!($i%$_)};$o-eq2*$i

Try it Online!

Edit: -3 bytes thanks to @AdmBorkBork

J. Bergmann

Posted 2019-03-12T02:41:31.763

Reputation: 221

43 bytes by rolling the accumulator into the loop and checking against 2*$i to eliminate the subtract-one parens. – AdmBorkBork – 2019-03-12T12:42:12.907

2

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 equals n

Code Explanation

: f                \ start word definition
  0 over 1         \ create a value to hold the sum and setup 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 the sum and n are equal
;                  \ end the word definition

reffu

Posted 2019-03-12T02:41:31.763

Reputation: 1 361

2

Smalltalk, 34 bytes

((1to:n-1)select:[:i|n\\i=0])sum=n

Leandro Caniglia

Posted 2019-03-12T02:41:31.763

Reputation: 181

1

Batch, 81 bytes

@set s=-%1
@for /l %%i in (1,1,%1)do @set/as+=%%i*!(%1%%%%i)
@if %s%==%1 echo 1

Takes n as a command-line parameter and outputs 1 if it is a perfect number. Brute force method, starts the sum at -n so that it can include n itself in the loop.

Neil

Posted 2019-03-12T02:41:31.763

Reputation: 95 035

1

Charcoal, 13 bytes

Nθ⁼θΣΦθ∧ι¬﹪θι

Try it online! Link is to verbose version of code. Outputs - for perfect numbers. Uses brute force. Explanation:

Nθ              Numeric input
     Φθ         Filter on implicit range
        ι       Current value (is non-zero)
       ∧        Logical And
           θ    Input value
          ﹪     Modulo
            ι   Current value
         ¬      Is zero
    Σ           Sum of matching values
  ⁼             Equals
   θ            Input value

Neil

Posted 2019-03-12T02:41:31.763

Reputation: 95 035

1

J42161217

Posted 2019-03-12T02:41:31.763

Reputation: 15 931

Yes, Mathematica! Another built-in. – tsh – 2019-03-12T10:21:19.427

1

Pyth, 8 bytes

qs{*MPyP

Try it online here.

qs{*MPyPQQ   Implicit: Q=eval(input())
             Trailing QQ inferred
       PQ    Prime factors of Q
      y      Powerset
     P       Remove last element - this will always be the full prime factorisation
   *M        Take product of each
  {          Deduplicate
 s           Sum
q        Q   Is the above equal to Q? Implicit print

Sok

Posted 2019-03-12T02:41:31.763

Reputation: 5 592

1

Retina 0.8.2, 44 bytes

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

Try it online! Uses brute force, so link only includes the faster test cases. Explanation:

.+
$*

Convert to unary.

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

Match all factors of the input. This uses overlapping mode, which in Retina 0.8.2 requires all of the matches to start at different positions, so the matches are actually returned in descending order, starting with the original input.

+`^1(1*¶+)1
$1

Subtract the proper factors from the input.

^¶+$

Test whether the result is zero.

Neil

Posted 2019-03-12T02:41:31.763

Reputation: 95 035

1

Java 8, 66 bytes


Someone has to use the stream API at some point, even if there's a shorter way to do it

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

Try it online!

Benjamin Urquhart

Posted 2019-03-12T02:41:31.763

Reputation: 1 262

1

cQuents, 8 bytes

?#N=U\zN

Try it online!

Explanation

?           Mode query: return whether or not input is in sequence
 #          Conditional: iterate N, add N to sequence if condition is true
  N=         Condition: N == 
    U    )                   sum(                  )
     \z )                        proper_divisors( )
       N                                         N
        ))    implicit

Stephen

Posted 2019-03-12T02:41:31.763

Reputation: 12 293

1

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!

Jonathan Allan

Posted 2019-03-12T02:41:31.763

Reputation: 67 804

1

Haskell, 35 bytes

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

Try it online!

Joseph Sible-Reinstate Monica

Posted 2019-03-12T02:41:31.763

Reputation: 556

1

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)

Ismael Miguel

Posted 2019-03-12T02:41:31.763

Reputation: 6 797

1

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

Jonathan Allan

Posted 2019-03-12T02:41:31.763

Reputation: 67 804

1

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?

Jonathan Allan

Posted 2019-03-12T02:41:31.763

Reputation: 67 804

1

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.

Galen Ivanov

Posted 2019-03-12T02:41:31.763

Reputation: 13 815

1

Racket, 54 bytes

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

Try it online!

Galen Ivanov

Posted 2019-03-12T02:41:31.763

Reputation: 13 815

1

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.

maxb

Posted 2019-03-12T02:41:31.763

Reputation: 5 754

1

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
        .sum()              add all divisors
          ==i                compare to the original number
             }               end lambda

Try it online!

Adam

Posted 2019-03-12T02:41:31.763

Reputation: 101

1

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

steenbergh

Posted 2019-03-12T02:41:31.763

Reputation: 7 772

1

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 

RosLuP

Posted 2019-03-12T02:41:31.763

Reputation: 3 036

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

Suever

Posted 2019-03-12T02:41:31.763

Reputation: 10 257

1

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?

Giuseppe

Posted 2019-03-12T02:41:31.763

Reputation: 21 077

0

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
000007A0  01D9              add ecx,ebx
000007A2  EBED              jmp short 0x791
000007A4  29C8              sub eax,ecx
000007A6  0F94C0            setz al
000007A9  0FB6C0            movzx eax,al
000007AC  5B                pop ebx
000007AD  C3                ret
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
      add     ecx,  ebx
      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

RosLuP

Posted 2019-03-12T02:41:31.763

Reputation: 3 036

0

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)

Expired Data

Posted 2019-03-12T02:41:31.763

Reputation: 3 129