\ $n\$- números perfeitos

Sep 14 2020

Um inteiro positivo \$x\$é um \$n\$- número perfeito se \$\sigma(x) = nx\$, onde \$\sigma(x)\$é a função de soma do divisor. Por exemplo, \$120\$é um \$3\$- número perfeito porque sua soma de divisores é \$360\$:

$$360 = 3\times120 = 1+2+3+4+5+6+8+10+12+15+20+24+30+40+60+120$$

e

$$926073336514623897600 = 6\times154345556085770649600 = 1+2+3+4+5+6+7+8+9+10+11+12+\dots+51448518695256883200+77172778042885324800+154345556085770649600$$

então \$154345556085770649600\$é um \$6\$- número perfeito.

Você deve pegar um inteiro \$x\$como entrada e saída de um valor \$n\$, tal que \$x\$é um \$n\$- número perfeito. Se não houver \$n\$existir, você pode gerar qualquer valor consistente que não seja um número inteiro positivo. Você nunca receberá uma entrada fora dos limites do seu idioma, mas seu algoritmo deve funcionar para \$x\$.

Este é o código-golfe, então o código mais curto em bytes vence.

Mini desafio: vença 5 bytes no Jelly

Casos de teste

    x -> n
    1 -> 1
    2 -> 0
    3 -> 0
    4 -> 0
    5 -> 0
    6 -> 2
   28 -> 2
  120 -> 3
  496 -> 2
  500 -> 0
  672 -> 3
30240 -> 4
154345556085770649600 -> 6

Respostas

9 Zgarb Sep 14 2020 at 11:28

Husk , 4 bytes

¦¹ΣḊ

Experimente online!

O último caso de teste expira.

Explicação

¦¹ΣḊ   Input is a number x.
   Ḋ   List of divisors.
  Σ    Sum.
¦      Division if divisible, 0 if not
 ¹     by x.

¦ geralmente é apenas um teste de divisibilidade, mas aqui seu valor de retorno é útil.

8 Sisyphus Sep 14 2020 at 10:59

Gelatina , 5 bytes

R×iÆs

Experimente online!

Explicação:

      - Explanation (sample for input 6)
R     - Range ([1, 2, 3, 4, 5, 6])
 ×    - Multiply by input ([6, 12, 18, 24, 30, 36])
   Æs - Divisor sum (12)
  i   - Index of divisor sum in list, else 0 (2)
7 xash Sep 14 2020 at 05:24

Brachylog , 6 bytes

f+;?/ℕ

Experimente online!

Como funciona

f+;?/ℕ
f+     the sum of the factors
  ;?/ℕ divided by the input
     ℕ is a natural number

Versão alternativa, acho que é mais legal, mas mais longa:

f+~×[?,.]∧
f+          the sum of the factors
  ~×        unifies with the multiplication of
    [?,.]   the input and the output
         ∧  return the output
6 Bismarck71 Sep 14 2020 at 14:36

05AB1E , 7 6 bytes

Ý*IÑOk

Experimente online!

Explicação:

Ý*IÑOk>
Ý        0-Index inclusive range of input (6 -> [1, 2, 3, 4, 5, 6])
 *       Multiply by input ([6, 12, 18, 24, 30, 36])
  IÑO    Get input -> divisors -> sum (6 -> [1, 2, 3, 6] -> 12)
     k   0-Index of divisor-sum in array or -1 if not found. ([6, >12<, 18, 24, 30, 36] -> 1)

Acabei de usar o método de Sísifo. Isso provavelmente poderia ser eliminado ou mesmo tornado mais eficiente, mas não tenho o conhecimento do 05AB1E para fazer isso. Só pensei em dar uma chance para passar o tempo.

-1 Byte graças a ovs

5 AZTECCO Sep 14 2020 at 07:30

C (gcc) , 47 bytes

s,i;f(x){for(i=s=x;--i;)s+=x%i?0:i;s/=s%x*s+x;}

Experimente online!

Retorna nou 0.

5 JoKing Sep 14 2020 at 11:23

APL (Dyalog Unicode) , 16 15 13 bytes

Obrigado ao Bubbler por apontar que posso alterar o formato de saída para economizar alguns bytes

⍸×∘⍳⍨=1⊥∘∪⊢∨⍳

Experimente online!

Produz uma lista de singleton de nquando nexiste e um array vazio caso contrário. Encontra o índice de ( ⍸) onde a soma de ( 1⊥) os divisores ( ∪⊢∨⍳) é igual a ( =) um múltiplo da entrada ( ×∘⍳⍨). Eu uso ⍸e em =vez de apenas ⍳encontrar o índice porque ele retorna uma lista vazia quando o elemento não está lá, em vez do comprimento da lista.

4 KevinCruijssen Sep 14 2020 at 16:17

Espaço em branco , 153 bytes

[S S S N
_Push_0][S N
S _Duplicate_0][T   N
T   T   _Read_STDIN_as_integer][T   T   T   _Retrieve_input][S N
S _Duplicate_input][S N
S _Duplicate_input][N
S S N
_Create_Label_LOOP][S S S T N
_Push_1][T  S S T   _Subtract][S N
S _Duplicate][N
T   S S N
_If_0_Jump_to_Label_REACHED_ZERO][S T   S S T   S N
_Copy_0-based_2nd_input][S T    S S T   N
_Copy_0-based_1st_integer][T    S T T   _Modulo][N
T   S T N
_If_0_Jump_to_Label_ADD_TO_SUM][N
S N
N
_Jump_to_Label_LOOP][N
S S T   N
_Create_Label_ADD_TO_SUM][S N
T   _Swap_top_two][S T  S S T   N
_Copy_0-based_1st_integer][T    S S S _Add_top_two][S N
T   _Swap_top_two][N
S N
N
_Jump_to_Label_LOOP][N
S S S N
_Create_Label_REACHED_ZERO][S N
N
_Discard_top][S N
S _Duplicate_top][S T   S S T   S N
_Copy_0-based_2nd_input][T  S T T   _Modulo][N
T   S S S N
_If_0_Jump_to_Label_DIVISIBLE][S S S N
_Push_0][N
S N
S T 
_Jump_to_Label_OUTPUT][N
S S S S N
_Create_Label_DIVISIBLE][S N
T   _Swap_top_two][T    S T S _Integer_divide_top_two][N
S S S T N
_Create_Label_OUTPUT][T N
S T _Output_as_integer]

Letras S(espaço), T(tabulação) e N(nova linha) adicionadas apenas como destaque.
[..._some_action]adicionado apenas como explicação.

Experimente online (apenas com espaços brutos, tabulações e novas linhas).

Explicação em pseudocódigo:

Integer input = STDIN as input
Integer sum = input
Integer i = input
Start LOOP:
  i = i - 1
  If(i == 0):
    Jump to Label REACHED_ZERO
  If(input % i == 0):
    sum = sum + i
  Go to next iteration of LOOP

Label REACHED_ZERO:
  Integer output
  If(sum % input == 0):
    output = sum integer-divided by input
  Else:
    output = 0

  Print output as integer to STDOUT

Exemplo de execução: input = 6

Command    Explanation                       Stack         Heap   STDIN  STDOUT  STDERR

SSSN       Push 0                            [0]
SNS        Duplicate top (0)                 [0,0]
TNTT       Read STDIN as integer             [0]           {0:6}  6
TTT        Retrieve at address (0)           [6]           {0:6}
SNS        Duplicate top (6)                 [6,6]         {0:6}
SNS        Duplicate top (6)                 [6,6,6]       {0:6}
NSSN       Create Label LOOP                 [6,6,6]       {0:6}
 SSSTN     Push 1                            [6,6,6,1]     {0:6}
 TSST      Subtract top two (6-1)            [6,6,5]       {0:6}
 SNS       Duplicate top (5)                 [6,6,5,5]     {0:6}
 NTSSN     If 0: Jump to Label REACHED_ZERO  [6,6,5]       {0:6}
 STSSTSN   Copy 0-based 2nd (6)              [6,6,5,6]     {0:6}
 STSSTN    Copy 0-based 1st (5)              [6,6,5,6,5]   {0:6}
 TSTT      Modulo top two (6%5)              [6,6,5,1]     {0:6}
 NTSTN     If 0: Jump to Label ADD_TO_SUM    [6,6,5]       {0:6}
 NSNN      Jump to Label LOOP                [6,6,5]       {0:6}

 SSSTN     Push 1                            [6,6,5,1]     {0:6}
 TSST      Subtract top two (5-1)            [6,6,4]       {0:6}
 SNS       Duplicate top (4)                 [6,6,4,4]     {0:6}
 NTSSN     If 0: Jump to Label REACHED_ZERO  [6,6,4]       {0:6}
 STSSTSN   Copy 0-based 2nd (6)              [6,6,4,6]     {0:6}
 STSSTN    Copy 0-based 1st (4)              [6,6,4,6,4]   {0:6}
 TSTT      Modulo top two (6%4)              [6,6,4,2]     {0:6}
 NTSTN     If 0: Jump to Label ADD_TO_SUM    [6,6,4]       {0:6}
 NSNN      Jump to Label LOOP                [6,6,4]       {0:6}

 SSSTN     Push 1                            [6,6,4,1]     {0:6}
 TSST      Subtract top two (4-1)            [6,6,3]       {0:6}
 SNS       Duplicate top (3)                 [6,6,3,3]     {0:6}
 NTSSN     If 0: Jump to Label REACHED_ZERO  [6,6,3]       {0:6}
 STSSTSN   Copy 0-based 2nd (6)              [6,6,3,6]     {0:6}
 STSSTN    Copy 0-based 1st (3)              [6,6,3,6,3]   {0:6}
 TSTT      Modulo top two (6%3)              [6,6,3,0]     {0:6}
 NTSTN     If 0: Jump to Label ADD_TO_SUM    [6,6,3]       {0:6}
 NSSTN     Create Label ADD_TO_SUM           [6,6,3]       {0:6}
  SNT      Swap top two                      [6,3,6]       {0:6}
  STSSTN   Copy 0-based 1st (3)              [6,3,6,3]     {0:6}
  TSSS     Add top two (6+3)                 [6,3,9]       {0:6}
  SNT      Swap top two                      [6,9,3]       {0:6}
  NSNN     Jump to Label LOOP                [6,9,3]       {0:6}

 SSSTN     Push 1                            [6,9,3,1]     {0:6}
 TSST      Subtract top two (3-1)            [6,9,2]       {0:6}
 SNS       Duplicate top (2)                 [6,9,2,2]     {0:6}
 NTSSN     If 0: Jump to Label REACHED_ZERO  [6,9,2]       {0:6}
 STSSTSN   Copy 0-based 2nd (6)              [6,9,2,6]     {0:6}
 STSSTN    Copy 0-based 1st (5)              [6,9,2,6,2]   {0:6}
 TSTT      Modulo top two (6%5)              [6,9,2,0]     {0:6}
 NTSTN     If 0: Jump to Label ADD_TO_SUM    [6,9,2]       {0:6}
  SNT      Swap top two                      [6,2,9]       {0:6}
  STSSTN   Copy 0-based 1st (2)              [6,2,9,2]     {0:6}
  TSSS     Add top two (9+2)                 [6,2,11]      {0:6}
  SNT      Swap top two                      [6,11,2]      {0:6}
  NSNN     Jump to Label LOOP                [6,11,2]      {0:6}

 SSSTN     Push 1                            [6,11,2,1]    {0:6}
 TSST      Subtract top two (2-1)            [6,11,1]      {0:6}
 SNS       Duplicate top (1)                 [6,11,1,1]    {0:6}
 NTSSN     If 0: Jump to Label REACHED_ZERO  [6,11,1]      {0:6}
 STSSTSN   Copy 0-based 2nd (6)              [6,11,1,6]    {0:6}
 STSSTN    Copy 0-based 1st (1)              [6,11,1,6,1]  {0:6}
 TSTT      Modulo top two (6%1)              [6,11,1,0]    {0:6}
 NTSTN     If 0: Jump to Label ADD_TO_SUM    [6,11,1]      {0:6}
  SNT      Swap top two                      [6,1,11]      {0:6}
  STSSTN   Copy 0-based 1st (1)              [6,1,11,1]    {0:6}
  TSSS     Add top two (11+1)                [6,1,12]      {0:6}
  SNT      Swap top two                      [6,12,1]      {0:6}
  NSNN     Jump to Label LOOP                [6,12,1]      {0:6}

 SSSTN     Push 1                            [6,12,1,1]    {0:6}
 TSST      Subtract top two (1-1)            [6,12,0]      {0:6}
 SNS       Duplicate top (1)                 [6,12,0,0]    {0:6}
 NTSSN     If 0: Jump to Label REACHED_ZERO  [6,12,0]      {0:6}
 NSSSN     Create Label REACHED_ZERO         [6,12,0]      {0:6}
  SNN      Discard top (0)                   [6,12]        {0:6}
  SNS      Duplicate top (12)                [6,12,12]     {0:6}
  STSSTSN  Copy 0-based 2nd (6)              [6,12,12,6]   {0:6}
  TSTT     Modulo top two (12%6)             [6,12,0]      {0:6}
  NTSSSN   If 0: Jump to Label DIVISIBLE     [6,12]        {0:6}
  NSSSSN   Create Label DIVISIBLE            [6,12]        {0:6}
   SNT     Swap top two                      [12,6]        {0:6}
   TSTS    Integer-divide top two (12/6)     [2]           {0:6}
   NSSSTN  Create Label OUTPUT               [2]           {0:6}
    TNST   Output top as integer (2)         []            {0:6}         2
                                                                                 error

Para com um erro após imprimir o resultado, porque nenhuma saída foi definida.

4 Mukundan314 Sep 14 2020 at 09:38

Pyth , 15 bytes

&!%Jsf!%QTSQQ/J

Experimente online!

Explicação

&!%Jsf!%QTSQQ/J
   J              # set J to
    s             # sum of
     f    SQ      # filtering the range [1, input] with
      !%QT        # lambda T: not (input % T)    (divisibility test)
                  # implicit print the
&                 # short-circuiting and of
 !%J        Q     # not (J % input)
             /J   # and J / input
3 Arnauld Sep 14 2020 at 04:59

JavaScript (ES6), 41 bytes

Retorna 0 se não houver solução.

x=>(g=k=>x=k&&k*!(x%k)/x+g(k-1))(x)%1?0:x

Experimente online!

3 JonathanAllan Sep 14 2020 at 05:22

Gelatina , 6 bytes

Æs0:%?

Um Link monádico que aceita um número inteiro positivo que produz um número inteiro não negativo.

Experimente online! Ou veja o conjunto de testes .

Quão?

Æs0:%? - Link: x
Æs     - divisor sum
     ? - if...
    %  - ...condition: has a remainder when divided
  0    - ...then: zero
    :  - ...else: integeger divide
3 Razetime Sep 14 2020 at 11:22

APL (Dyalog Unicode) , 19 18 bytes

⊢(÷⍨×0=|)1⊥∘⍸0=⍳|⊢

Experimente online!

Conversão para treinar por Jo King. (- 3 bytes)

-1 byte a mais de Jo King após alterar a condição de verificação.

Resposta mais antiga, 22 bytes

{(⊢×⌊=⊢)⍵÷⍨+/⍸0=⍵|⍨⍳⍵}

Explicação

{(⊢×⌊=⊢)⍵÷⍨+/⍸0=⍵|⍨⍳⍵} ⍵ → input
                   ⍳⍵  range 1-⍵
                ⍵|⍨    mod ⍵
              0=       check which ones are divisors
             ⍸         get the indices (factors)
           +/          sum the factors
        ⍵÷⍨            divide by ⍵
 (⊢×⌊=⊢)               Inner tacit fn:
    ⌊=⊢                Floor equals right? (integer test, returns 0 or 1)
  ⊢×                   times right 
3 ovs Sep 14 2020 at 06:15

Haskell , 51 46 bytes

a!b=0^mod a b*div a b
f n=sum(map(n!)[1..n])!n

Experimente online!

3 J42161217 Sep 14 2020 at 06:24

Linguagem Wolfram (Mathematica) , 30 bytes

Tr@Divisors@#/#/._Rational->0&

Experimente online!

-6 bytes de @att

3 Neil Sep 14 2020 at 05:55

Carvão , 23 20 bytes

NθI⌕E⊕θ×θιΣΦ⊕θ∧ι¬﹪θι

Experimente online! O link é para a versão detalhada do código. Porta do algoritmo de @Sisyphus, mas usando o comentário de @ ovs para lidar com a indexação 0. Saídas -1por inexistência. Explicação:

Nθ                      Input `x` as a number
             θ          `x`
            ⊕           Incremented
           Φ            Filter over implicit range
               ι        Current index
              ∧         Logical AND
                  θ     `x`
                 ﹪      Modulo
                   ι    Current index
                ¬       Logical NOT
          Σ             Take the sum
      θ                 `x`
     ⊕                  Incremented
    E                   Map over implicit range
        θ               `x`
       ×                Multiplied by
         ι              Current index
   ⌕                    Find the index
  I                     Cast to string
                        Implicitly print

Infelizmente para Charcoal a soma de []não é zero, o que significa que não posso salvar um byte removendo os dois incrementos de xe incrementando o resultado.

Solução anterior de 23 bytes:

Nθ≔ΣΦ⊕θ∧ι¬﹪θιη¿¬﹪ηθI÷ηθ

Experimente online! O link é para a versão detalhada do código. Explicação:

Nθ

Entrada x.

≔ΣΦ⊕θ∧ι¬﹪θιη

Crie uma lista de 1..x, filtre os números que não se dividem xe faça a soma.

¿¬﹪ηθI÷ηθ

Se xdividir a soma, imprima o quociente.

3 DominicvanEssen Sep 14 2020 at 14:55

R , 42 41 39 bytes

Editar: -1 byte (e, inspirado nisso, mais -2 bytes) graças a Robin Ryder

function(x)(d=sum(1:x*!x%%1:x))/x*!d%%x

Experimente online!

Comentado:

perfect_n=
function(x)
 (d=            # d is the divisor sum, calculated as...
  sum(          # sum of...
   1:x*         # the values of 1..x that have...
    !           # zero values for...
     x%%1:x)    # x MOD 1..x
  )
 )/x            # output d/x...
    *!d%%x      # but only if it's an integer 
                # (so d MOD x == 0)
2 user Sep 14 2020 at 05:38

Scala, 54 53 bytes

x=>{val s=1 to x filter(x%_<1)sum;s/x*(1-(s%x).sign)}

Experimente no Scastie

Soma todos os divisores de x1 a x, inclusive. Se essa soma for divisível por x, ele retorna aquele dividido por x, caso contrário, retorna 0.

2 Neil Sep 14 2020 at 06:05

Retina , 51 bytes

.+
*
|""Lw`^(.+)(?=\1*$) ^ $-1;
L$`^(.+);(\1)+$
$#2

Experimente online! O link inclui casos de teste menos lentos. Explicação:

.+
*

Converta a entrada em unário.

|""Lw`^(.+)(?=\1*$)

Liste todos os fatores sem delimitá-los, somando-os.

^
$-1;

Recupere o valor unário original.

L$`^(.+);(\1)+$ $#2

Conte quantas vezes ele divide a soma. (Ou não produza nada se isso não acontecer.)

2 LuisMendo Sep 14 2020 at 06:33

Octave , 36 34 bytes

@(x)~mod(s=~mod(x,r=1:x)*r',x)*s/x

Função anônima que recebe um ponto flutuante ou número inteiro como entrada. O último caso de teste falha devido a limitações de memória.

Experimente online! Ou verifique casos de teste .

Explicação

@(x)~mod(s=~mod(x,r=1:x)*r',x)*s/x

@(x)                                 % anonymous function with input x
                    1:x              % row vector [1 2 ... x]
                  r=                 % call that r
            mod(x,     )             % x modulo [1 2 ... x]. Gives a row vector
           ~                         % negate each element. Gives 1 for divisors
                         r'          % column vector [1; 2; ... ; x]
                        *            % matrix-multiply. Gives the sum of divisors
         s=                          % call that s
     mod(                  ,x)       % sum of divisors modulo x
    ~                                % negate. Gives 1 if x divides sum of divisors
                               s/x   % sum of divisors divided by x
                              *      % multiply
2 Mukundan314 Sep 14 2020 at 12:10

Python 3.8 (pré-lançamento) , 62 bytes

lambda x:(a:=sum(x/i*(x%i<1)for i in range(1,x+1)))%x<1and a/x

Experimente online!

2 KevinCruijssen Sep 14 2020 at 17:29

MathGolf , 7 bytes

─Σk‼÷/*

Experimente online.

Explicação:

─       # Get the divisors of the (implicit) input-integer
 Σ      # Sum those divisors
  k     # Push the input-integer again
   ‼    # Apply the following two commands separately to the stack:
    ÷   #  Check if the divisor-sum is divisible by the input (1 if truthy; 0 if falsey)
    /   #  Integer-divide the divisor-sum by the input
     *  # Multiply the two together
        # (after which the entire stack joined together is output implicitly as result)
2 Shaggy Sep 14 2020 at 18:22

Rockstar , 141 135 131 bytes

Não produz nada se não nexistir.

listen to N
X's0
T's0
while N-X
let X be+1
let D be N/X
turn up D
let T be+D is N/X and X

let D be T/N
turn up D
if D is T/N
say D

Experimente aqui (o código terá de ser colado)

1 GalenIvanov Sep 14 2020 at 13:51

Ícone , 67 bytes

procedure f(n)
s:=0
n%(i:=1to n)=0&s+:=i&\z
return(0=s%n&s/n)|0
end

Experimente online!

1 Shaggy Sep 14 2020 at 14:00

Japt -æ , 7 bytes

Saídas undefinedse nenhum nfor encontrado.

*N¶Îâ x

Tente

1 GalenIvanov Sep 14 2020 at 14:17

Fator , 84 bytes

: f ( n -- n ) dup [1,b] [ dupd mod 0 = ] filter sum swap /mod 0 > [ drop 0 ] when ;

Experimente online!

1 user Sep 15 2020 at 02:19

Prolog, 117 bytes

s(X,D,S):-D<1,!,S is 0;E is D-1,(0 is X mod D,!,s(X,E,T),S is T+D;s(X,E,S)).
f(X,N):-s(X,X,S),0 is S mod X,N is S//X.

Experimente online! (Por favor, não o modifique diretamente, isso mudaria minha versão também)


Se alguém pudesse descobrir por que esta versão mais curta (96 bytes) não está funcionando, eu ficaria muito grato.

s(X,D,S):-D<1,!,S is 0;E is D-1,(0 is X mod D,!,s(X,E,T),S is T+D;s(X,E,S)).
f(X,N):-s(X,X,N*X).

Versão com depuração de impressão

1 2014MELO03 Sep 17 2020 at 02:48

GolfScript , 22 bytes

~:x),{.x\%!*+}*.x%!*x/

Experimente online!

~:x                     # Store the input in x
   ),                   # Make an array from 0 to x
     {       }*         # For each number in the array, execute this block
      .                 # Copy current number
       x\%!             # The copy becomes 1 if it is a divisor of x and 0 if it isn't
           *+           # Multiply and add
               .        # Copy the sum of the divisors
                x%!     # The copy becomes 1 if it is a divisor of x and 0 if it isn't
                   *    # Multiply
                    x/  # Divide by x