Mistura adequada do divisor

20

Um divisor apropriado é um divisor de um número n , que não é n em si. Por exemplo, os divisores adequados de 12 são 1, 2, 3, 4 e 6.

Você receberá um número inteiro x , x ≥ 2, x ≤ 1000 . Sua tarefa é somar todos os divisores apropriados mais altos de números inteiros de 2 a x (inclusive) (OEIS A280050 ).

Exemplo (com x = 6):

  • Encontre todos os números inteiros entre 2 e 6 (inclusive): 2,3,4,5,6.

  • Obtenha os divisores adequados de todos eles e escolha os mais altos de cada número:

    • 2 -> 1
    • 3 -> 1
    • 4 -> 1, 2
    • 5 -> 1
    • 6 -> 1, 2, 3 .
  • Resumir os mais altos divisores apropriados: 1 + 1 + 2 + 1 + 3 = 8.

  • O resultado final é 8.

Casos de teste

Entrada | Saída
------- + ---------
       |
 2 1
 4 4
 6 8
 8 13
 15 41.
 37 229
 100 1690
 1000 165279

Regras

Mr. Xcoder
fonte
Caixa de areia.
Mr. Xcoder
5
Se você estiver indo para o sandbox de algo, deixe-o lá por mais de duas horas.
Peter Taylor
@PeterTaylor Coloquei na caixa de areia a postagem apenas para receber feedback, porque esse é um desafio muito simples que eu normalmente não colocaria na caixa de areia. BTW obrigado pela edição.
Mr. Xcoder

Respostas:

13

Oásis , 4 bytes

Código:

nj+U

Experimente online!

Explicação:

Versão extendida:

nj+00

    0   = a(0)
   0    = a(1)

a(n) =

n       # Push n
 j      # Get the largest divisor under n
  +     # Add to a(n - 1)
Adnan
fonte
5

Casca , 7 bytes

ṁȯΠtptḣ

Experimente online!

Explicação

Husk não tem built-in para calcular os divisores diretamente (ainda), então estou usando a fatoração primária. O maior divisor próprio de um número é o produto de seus fatores primos, exceto o menor. Eu mapeio essa função no intervalo de 2 à entrada e soma os resultados.

ṁȯΠtptḣ  Define a function:
      ḣ  Range from 1 to input.
     t   Remove the first element (range from 2).
ṁ        Map over the list and take sum:
 ȯ        The composition of
    p     prime factorization,
   t      tail (remove smallest prime) and
  Π       product.
Zgarb
fonte
5

Python 2 , 50 bytes

f=lambda n,k=2:n/k and(f(n,k+1),n/k+f(n-1))[n%k<1]

Isso é lento e nem consegue lidar com a entrada 15 no TIO.

Experimente online!

No entanto, a memorização ( obrigado @ musicman523 ) pode ser usada para verificar todos os casos de teste.

Experimente online!

Versão alternativa, 52 bytes

Ao custo de 2 bytes, podemos escolher entre calcular f(n,k+1)ou n/k+f(n-1).

f=lambda n,k=2:n>1and(n%k and f(n,k+1)or n/k+f(n-1))

Com alguns truques, isso funciona para todos os casos de teste, mesmo no TIO.

Experimente online!

Dennis
fonte
Desde fé uma função pura , você pode memoize-lo para executar os casos maiores em TIO
musicman523
Certo, não poder usar um decorador me assustou. Obrigado!
Dennis
4

Gelatina , 6 bytes

ÆḌ€Ṫ€S

Experimente online!

Como funciona

ÆḌ€Ṫ€S
ÆḌ€    map proper divisor (1 would become empty array)
           implicitly turns argument into 1-indexed range
   Ṫ€  map last element
     S sum
Freira Furada
fonte
4

JavaScript (ES6), 40 bytes

f=(n,i=2)=>n<2?0:n%i?f(n,i+1):n/i+f(n-1)
<input type=number oninput=o.textContent=f(this.value)><pre id=o>

Um número é igual ao produto do seu maior divisor próprio e do menor fator primo.

Neil
fonte
estouro de pilha para n>352(pelo menos neste trecho, não sei se é a dependência do meu navegador / máquina) enquanto você deveria suportar pelo menos até n=1000.
officialaimm
@officialaimm Funciona n=1000se você usar, por exemplo node --stack_size=8000.
30517 Neil
4

05AB1E , 9 8 bytes

-1 Byte, graças ao truque principal de Leaky Nun em sua resposta Pyth

L¦vyÒ¦PO

Experimente online!

Explicação

L¦vyÒ¦PO
L¦       # Range [2 .. input]
  vy     # For each...
    Ò¦    # All prime factors except the first one
      P   # Product
       O  # Sum with previous results
         # Implicit print

Solução alternativa de 8 bytes (que não funciona no TIO)

L¦vyѨθO    

e ofc solução alternativa de 9 bytes (que funciona no TIO)

L¦vyѨ®èO    
Datboi
fonte
4

Retina , 31 24 bytes

7 bytes graças a Martin Ender.

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

Experimente online!

Como funciona

O regex /^(1+)\1+$/captura o maior divisor próprio de um determinado número representado em unário. No código, o \1+é transformado em uma sintaxe lookahead.

Freira Furada
fonte
4

Mathematica, 30 bytes

Divisors[i][[-2]]~Sum~{i,2,#}&
J42161217
fonte
4

Pitão , 13 9 8 bytes

1 byte graças ao jacoblaw.

tsm*FtPh

Conjunto de teste .

Como funciona

O maior divisor apropriado é o produto dos fatores primos, exceto o menor.

Freira Furada
fonte
8 bytes
jacoblaw
4

Python 2 (PyPy) , 73 71 70 bytes

n=input();r=[0]*n;d=1
while n:n-=1;r[d+d::d]=n/d*[d];d+=1
print sum(r)

Não é a resposta mais curta do Python, mas isso apenas passa pelos casos de teste. O TIO lida com entradas de até 30.000.000 sem suar a camisa; meu computador de mesa lida com 300.000.000 em um minuto.

Com o custo de 2 bytes , a condição n>dpode ser usada para uma aceleração de ~ 10%.

Agradecemos a @xnor pela r=[0]*nideia, que salvou 3 bytes!

Experimente online!

Dennis
fonte
Engraçado, acabei de escrever basicamente o mesmo código .
xnor
l=[0]*ndeve permitir que você se livre -2. execmeio que mata a velocidade, mas mesmo um whileloop seria mais curto do que minha abordagem.
Dennis
Isso parece ser marginalmente mais rápido do que minha abordagem. Se importa se eu editar isso na minha resposta?
Dennis
Por favor, vá em frente.
xnor
1
@ Mr.Xcoder Não no PyPy, mas sim, as peneiras funcionam bem para esse tipo de problema.
Dennis
4

Haskell, 48 46 43 bytes

f 2=1
f n=until((<1).mod n)pred(n-1)+f(n-1)

Experimente online!

Edit: @rogaos salvou dois bytes. Obrigado!

Edite II: ... e @xnor mais 3 bytes.

nimi
fonte
-2 bytes:f 2=1 f n=last[d|d<-[1..n-1],mod n d<1]+f(n-1)
vroomfondel
@rogaos: Obrigado! Eu mesmo tentei a recursão explícita, mas não a removi sum, então pensei que não era mais curta.
N
1
untileconomiza um pouco mais:until((<1).mod n)pred(n-1)+f(n-1)
xnor 25/06
4

Japt , 8 + 2 = 10 8 6 bytes

òâ1 xo

Teste-o

  • 1 byte economizado graças à ETHproductions.

Explicação

    :Implicit input of integer U.
ò   :Generate an array of integers from 1 to U, inclusive
â   :Get the divisors of each number,
1   :  excluding itself.
x   :Sum the main array
o   :by popping the last element from each sub-array.
    :Implicit output of result
Shaggy
fonte
Observe que -xconta como dois bytes de acordo com este post . No entanto, eu acho que você pode salvar um byte com ò2_â1 o( âexclui o número original quando dado um argumento)
ETHproductions
Obrigado, @ETHproductions; Eu tinha perdido as duas coisas. Gostaria de saber se isso se aplica retroativamente a todas as soluções em que contamos sinalizadores como 1 byte? Eu estava trabalhando em uma solução alternativa que não usava uma bandeira; apontar o âargumento me deu a economia que eu estava procurando.
Shaggy
Eu diria que sim, já que não estávamos realmente seguindo um consenso antes. BTW, eu tinha jogado com õ Åantes e encontrei um par 8 e 9 byters: õ Åx_/k g, õ Åx_k Å×, õ Åx_â¬o. E, combinando õe Åcom seu xotruque genial, eu encontrei uma solução de 7 bytes :-)
ETHproductions
3

MATL, 12 bytes

q:Q"@Z\l_)vs

Experimente no MATL Online

Explicação

        % Implicitly grab input (N)
q       % Subtract one
:       % Create an array [1...(N-1)]
Q       % Add one to create [2...N]
"       % For each element
  @Z\   % Compute the divisors of this element (including itself)
  l_)   % Grab the next to last element (the largest that isn't itself)
  v     % Vertically concatenate the entire stack so far
  s     % Sum the result
Suever
fonte
3

Prolog (SWI) , 72 bytes

f(A,B):-A=2,B=1;C is A-1,f(C,D),between(2,A,E),divmod(A,E,S,0),B is D+S.

Experimente online!

Freira Furada
fonte
3

Cubix , 27 39 bytes

?%\(W!:.U0IU(;u;p+qu.@Op\;;

Experimente online!

Cubificado

      ? % \
      ( W !
      : . U
0 I U ( ; u ; p + q u .
@ O p \ ; ; . . . . . .
. . . . . . . . . . . .
      . . .
      . . .
      . . .

Assista

  • 0IUConfigure a pilha com um acumulador e o número inteiro inicial. Inversão de marcha em U para o circuito externo
  • :(? duplicar a parte superior atual da pilha, diminuir e testar
  • \pO@ se o loop for zero ao redor do cubo em um espelho, pegue o fundo da pilha, produza e pare
  • %\! se positivo, mod, relete e teste.
    • u;.W se for verdade, faça inversão de marcha, remova o resultado do mod e a faixa volte ao loop interno
    • U;p+qu;;\(se falsey, inversão de marcha, remova o resultado da modificação, coloque o acumulador no topo, adicione o divisor inteiro atual (superior) ao empurrão para baixo e inversão de marcha. Limpe a pilha para ter apenas o acumulador e o número inteiro atual, diminua o número inteiro e insira o loop externo novamente.
MickyT
fonte
3

C # (.NET Core) , 74 72 bytes

n=>{int r=0,j;for(;n>1;n--)for(j=n;--j>0;)if(n%j<1){r+=j;j=0;}return r;}

Experimente online!

  • 2 bytes raspados graças a Kevin Cruijssen.
Charlie
fonte
1
Eu sei que tem sido cerca de um ano, mas você pode golfe breakpara j=0.
Kevin Cruijssen
@KevinCruijssen um truque muito simples, mas eficaz. Boa ideia!
30618 Charlie
2

Python 3 , 78 75 73 71 bytes

Nem mesmo perto da resposta em python da freira Leaky na contagem de bytes.

f=lambda z:sum(max(i for i in range(1,y)if 1>y%i)for y in range(2,z+1))

Experimente online!

officialaimm
fonte
1
Você está chegando perto da primeira revisão da minha resposta ... pode verificar meu histórico de edições.
precisa
Oh, haha ... Juro que não roubei ... :)
officialaimm
2

Python 3 , 69 63 59 bytes

4 bytes graças a Dennis.

f=lambda n:n-1and max(j for j in range(1,n)if n%j<1)+f(n-1)

Experimente online!

Defino o limite de recursão para 2000 para que isso funcione para 1000.

Freira Furada
fonte
+1 Você tem meus pontos de brownie! Essa é a solução que eu estava falando quando diz "mais curto do que 70 bytes" ...
Mr. Xcoder
Além disso, isso também funciona no Python 2
Mr. Xcoder
2

Carvão , 37 bytes

A⁰βF…·²N«A⟦⟧δF⮌…¹ι«¿¬﹪ικ⊞δκ»A⁺β⌈δβ»Iβ

Experimente online!

O link é para a versão detalhada. Levei quase todo o dia para descobrir como resolver uma questão não relacionada à arte ASCII em Charcoal, mas finalmente entendi e tenho muito orgulho de mim. :-D

Sim, tenho certeza que isso pode ser muito praticado. Acabei de traduzir minha resposta em C # e tenho certeza de que as coisas podem ser feitas de maneira diferente no carvão vegetal. Pelo menos resolve o1000 caso em alguns segundos ...

Charlie
fonte
2

Python 2 (PyPy) , 145 bytes

Como transformar competições de código-golfe em competições de código mais rápido é divertido, aqui está um algoritmo O ( n ) que, no TIO, resolve n = 5.000.000.000 em 30 segundos. ( A peneira de Dennis é O ( n log n ).)

import sympy
n=input()
def g(i,p,k,s):
 while p*max(p,k)<=n:l=k*p;i+=1;p=sympy.sieve[i];s-=g(i,p,l,n/l*(n/l*k+k-2)/2)
 return s
print~g(1,2,1,-n)

Experimente online!

Como funciona

Contamos o tamanho do conjunto

S = {( a , b ) | 2 ≤ an , 2 ≤ b ≤ maior divisor próprio ( a )},

reescrevendo-a como a união, sobre todos os primos p ≤ √n, de

S p = {( pd , b ) | 2 ≤ dn / p , 2 ≤ bd },

e usando o princípio de inclusão-exclusão :

| S | = ∑ (−1) m - 1 | S p 1 ∩ ⋯ S p m | acima de m ≥ 1 e inicia p 1 <⋯ < p m ≤ √n,

Onde

S p 1p S p m = {( p 1p me , b ) | 1 ≤ en / ( p 1p m ), 2 ≤ bp 1p m - 1 e },
| S p 1 ∩ ⋯ S p m | = ⌊ n / ( p 1p m ) ⌋⋅ ( p 1p m - 1 ⋅ (⌊ n / ( p 1p m ) ⌋ + 1) - 2) / 2.

A soma tem Cn termos diferentes de zero, onde C converge para alguma constante que é provavelmente 6 ⋅ (1 - ln 2) / π 2 ≈ 0,186544. O resultado final é então | S | + n - 1.

Anders Kaseorg
fonte
Oooh, que é rápido ...
Mr. Xcoder
2

NewStack , 5 bytes

Felizmente, na verdade há um embutido.

Nᵢ;qΣ

O colapso:

Nᵢ       Add the first (user's input) natural numbers to the stack.
  ;      Perform the highest factor operator on whole stack.
   q     Pop bottom of stack.
    Σ    Sum stack.

Em inglês real:

Vamos executar um exemplo para uma entrada 8.

Nᵢ: Faça uma lista de números naturais de 1 a 8: 1, 2, 3, 4, 5, 6, 7, 8

;: Calcule os maiores fatores: 1, 1, 1, 2, 1, 3, 1, 4

q. Remova o primeiro elemento:1, 1, 2, 1, 3, 1, 4

ΣE pegue a soma: 1+1+2+1+3+1+4=13

Graviton
fonte
1+1+2+1+3+1+4= 13não 8. Além disso: ótima resposta, então +1.
Kevin Cruijssen
@KevinCruijssen Opa, obrigado por assistir!
precisa
2

Java 8, 78 74 72 bytes

n->{int r=0,j;for(;n>1;n--)for(j=n;j-->1;)if(n%j<1){r+=j;j=0;}return r;}

Porto da resposta C # de @CarlosAlejo .

Experimente aqui.

Resposta antiga (78 bytes):

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

Experimente aqui.

Explicação (da resposta antiga):

n->{                    // Method with integer parameter and integer return-type
  int r=0,              //  Result-integers
      i=1,j,k;          //  Some temp integers
  for(;++i<=n;          //  Loop (1) from 2 to `n` (inclusive)
      r+=k)             //    And add `k` to the result after every iteration
    for(j=1,k=1;++j<i;  //   Inner loop (2) from `2` to `i` (exclusive)
      k=i%j<1?j:k       //    If `i` is dividable by `j`, replace `k` with `j`
    );                  //   End of inner loop (2)
                        //  End of loop (2) (implicit / single-line body)
  return r;             //  Return result-integer
}                       // End of method
Kevin Cruijssen
fonte
1

Empilhados , 31 bytes

[2\|>[divisors:pop\MAX]map sum]

Experimente online!(Todos os casos de teste, exceto 1000, que excedem o limite de tempo on-line de 60 segundos.)

Explicação

[2\|>[divisors:pop\MAX]map sum]
 2\|>                               range from 2 to the input inclusive
     [                ]map          map this function over the range
      divisors                      get the divisors of the number (including the number)
              :pop\                 pop a number off the array and swap it with the array
                   MAX              gets the maximum value from the array
                           sum      sum's all the max's
Conor O'Brien
fonte
1

C (gcc) , 53 bytes

x;s;f(n){for(s=0;n>1;--n){for(x=n;n%--x;);s+=x;}n=s;}

Experimente online!

Confortavelmente, passa rapidamente em todos os casos de teste.

Conor O'Brien
fonte
51 bytes
ceilingcat