Soma os poderes que estão

35

Um desafio simples, mas espero que não seja trivial:

Escreva um programa ou função que adicione os kth poderes dividindo um número n. Mais especificamente:

  • Entrada: dois números inteiros positivos ne k(ou um par ordenado de números inteiros, etc.)
  • Saída: a soma de todos os divisores positivos dos nquais são as kpotências de números inteiros

Por exemplo, 11! = 39916800 possui seis divisores que são cubos, ou seja, 1, 8, 27, 64, 216 e 1728. Portanto, dadas as entradas 39916800e 3, o programa deve retornar sua soma 2044,.

Outros casos de teste:

{40320, 1} -> 159120
{40320, 2} -> 850
{40320, 3} -> 73
{40320, 4} -> 17
{40320, 5} -> 33
{40320, 6} -> 65
{40320, 7} -> 129
{40320, 8} -> 1
{46656, 1} -> 138811
{46656, 2} -> 69700
{46656, 3} -> 55261
{46656, 4} -> 1394
{46656, 5} -> 8052
{46656, 6} -> 47450
{46656, 7} -> 1
{1, [any positive integer]} -> 1

Isso é código de golfe, portanto, quanto menor o seu código, melhor. Congratulo-me com o código de golfe em todos os tipos de idiomas diferentes, mesmo que algum outro idioma possa se livrar com menos bytes que o seu.

Greg Martin
fonte
12
Quando vi seu desafio pela primeira vez, tive a estranha sensação de que era um título de música do Metallica.
Arnauld
11
O que? Não existe o Mathematica embutido para isso?
boboquack

Respostas:

13

05AB1E , 9 bytes

DLImDŠÖÏO

Experimente online!

Explicação

Exemplo de entrada 46656, 3

D          # duplicate first input
           # STACK: 46656, 46656
 L         # range [1 ... first input]
           # STACK: 46656, [1 ... 46656]
  Im       # each to the power of second input
           # STACK: 46656, [1, 8, 27 ...]
    D      # duplicate
           # STACK: 46656, [1, 8, 27 ...], [1, 8, 27 ...]
     Š     # move down 2 spots on the stack
           # STACK: [1, 8, 27 ...], 46656, [1, 8, 27 ...]
      Ö    # a mod b == 0
           # STACK: [1, 8, 27 ...], [1,1,1,1,0 ...]
       Ï   # keep only items from first list which are true in second
           # STACK: [1, 8, 27, 64, 216, 729, 1728, 5832, 46656]
        O  # sum
           # OUTPUT: 55261
Emigna
fonte
6

Mathematica, 28 bytes

Tr[Divisors@#⋂Range@#^#2]&

Função sem nome ne kcomo entradas nessa ordem.

Martin Ender
fonte
2
DivisorSumé frustrantemente próximo de ser útil aqui.
Ngenisis
5

Haskell , 37 35 34 bytes

n!k=sum[x^k|x<-[1..n],n`mod`x^k<1]

Experimente online! Uso:

Prelude> 40320 ! 1
159120

O código é bastante ineficiente porque sempre calcula 1^k, 2^k, ..., n^k.

Editar: salvou um byte graças ao Zgarb.

Explicação:

n!k=             -- given n and k, the function ! returns
 sum[x^k|        -- the sum of the list of all x^k
   x<-[1..n],    -- where x is drawn from the range 1 to n
   n`mod`x^k<1]  -- and n modulus x^k is less than 1, that is x^k divides n
Laikoni
fonte
11
mod n(x^k)pode ser n`mod`x^k.
Zgarb
5

Python 2, 54 52 bytes

lambda x,n:sum(i**n*(x%i**n<1)for i in range(1,-~x))

Obrigado @Rod por cortar 2 bytes.

hashcode55
fonte
Você pode substituir x%i**n==0por x%i**n<1e passar para o outro lado comoi**n*(x%i**n<1)
Rod
4

Ruby, 45 bytes

->n,m{(1..n).reduce{|a,b|n%(c=b**m)<1?a+c:a}}

Seria mais curto usando "sum" no Ruby 2.4. Hora de atualizar?

GB
fonte
4
Hora de atualizar.
Yytsi
4

MATL , 10 bytes

t:i^\~5M*s

Experimente online!

Como funciona

Exemplo com 46656, 6.

t      % Implicitly input n. Duplicate
       % STACK: 46656, 46656
:      % Range
       % STACK: 46656, [1 2 ... 46656]
i      % Input k
       % STACK: 46656, [1 2 ... 46656], 6
^      % Power, element-wise
       % STACK: 46656, [1 64 ... 46656^6]
\      % Modulo
       % STACK: [0 0 0 1600 ...]
~      % Logically negate
       % STACK: [true true true false ...]
5M     % Push second input to function \ again
       % STACK: [true true true false ...], [1^6 2^6 ... 46656^6]
*      % Multiply, element-wise
       % STACK: [1 64 729 0 ...]
s      % Sum of array: 47450
       % Implicitly display
Luis Mendo
fonte
4

Geléia , 7 6 bytes

-1 byte graças a Dennis (percorra um intervalo implícito)
Uma eficiência inteligente economizada também por Dennis a um custo de 0 byte
(Anteriormente ÆDf*€S, o filtro manteria os divisores que são uma potência de k de qualquer número natural até n . Mas observe que n pode só tenha um divisor de i k se tiver um divisor de i de qualquer maneira!)

ÆDf*¥S

Experimente online!

Quão?

ÆDf*¥S - Main link: n, k
ÆD     - divisors of n  -> divisors = [1, d1, d2, ..., n]
    ¥  - last two links as a dyadic chain
  f    -     filter divisors keeping those that appear in:
   *   -     exponentiate k with base divisors (vectorises)
       - i.e. [v for v in [1, d1, d2, ..., n] if v in [1^k, d1^k, ..., n^k]]
     S - sum
Jonathan Allan
fonte
3

JavaScript (ES7), 56 53 bytes

Toma ne kna currying sintaxe (n)(k).

n=>k=>[...Array(n)].reduce(p=>n%(a=++i**k)?p:p+a,i=0)

Casos de teste

Arnauld
fonte
3

Perl 6 , 39 bytes

->\n,\k{sum grep n%%*,({++$**k}...*>n)}

Como funciona

->\n,\k{                              }  # A lambda taking two arguments.
                        ++$              # Increment an anonymous counter
                           **k           # and raise it to the power k,
                       {      }...       # generate a list by repeatedly doing that,
                                  *>n    # until we reach a value greater than n.
            grep n%%*,(              )   # Filter factors of n from the list.
        sum                              # Return their sum.

Tente

smls
fonte
2

Japonês , 10 bytes

Economizou muitos bytes graças a @ETHproductions

òpV f!vU x

Explicação

òpV f!vU x
ò           // Creates a range from 0 to U
 pV         // Raises each item to the power of V (Second input)
    f       // Selects all items Z where
     !vU    //   U is divisible by Z
            //   (fvU would mean Z is divisible by U; ! swaps the arguments)
         x  // Returns the sum of all remaining items

Teste online!

Oliver
fonte
Será vUdetectar números divisíveis por U, ou números que divide U?
Greg Martin
@GregMartin fvUfiltra itens que são divisíveis por U; f!vUfiltra itens que Usão divisíveis por. !troca os argumentos.
1013 Oliver Oliver
Legal, o código parece correto, mas a explicação pode precisar ser aprimorada.
Greg Martin
@GregMartin Deve ficar mais claro agora.
ETHproductions
2

Scala 63 bytes

(n:Int,k:Int)=>1 to n map{Math.pow(_,k).toInt}filter{n%_==0}sum
jaxad0127
fonte
2

Python 2 , 50 bytes

f=lambda n,k,i=1:n/i and(n%i**k<1)*i**k+f(n,k,i+1)

Experimente online! Entradas grandes podem exceder a profundidade da recursão, dependendo do seu sistema e implementação.

xnor
fonte
2

JavaScript (ES7), 49 46 bytes

n=>g=(k,t=i=0,p=++i**k)=>p>n?t:g(k,t+p*!(n%p))
Neil
fonte
Como você não está recorrendo, por que não n=>k=>? +1.
Yytsi
@TuukkaX Eu vim com algo melhor. (Eu realmente tive isso antes com icomo um local, que custa 4 bytes extras, e se esqueceu de que eu poderia abusar ida mesma maneira que eu fiz com a minha outra formulação.)
Neil
1

PHP, 86 bytes

$n=$argv[1];$k=$argv[2];for($i=1;$i<=$n**(1/$k);$i++)if($n%$i**$k<1)$s+=$i**$k;echo$s;

Experimente aqui!

Demolir :

$n=$argv[1];$k=$argv[2];       # Assign variables from input
for($i=1;$i<=$n**(1/$k);$i++)  # While i is between 1 AND kth root of n
    if($n%$i**$k<1)            #     if i^k is a divisor of n
        $s+=$i**$k;            #         then add to s
echo$s;                        # echo s (duh!)
roberto06
fonte
golfado, mas não testado: for(;$x<$n=$argv[1];)$n%($x=++$i**$argv[2])?:$s+=$x;echo$s;59 bytes; requer PHP 5.6 ou posterior.
Titus
1

CJam , 20 bytes

Provavelmente não é o ideal, mas não vejo nenhuma mudança óbvia a ser feita ...

ri:N,:)rif#{N\%!},:+

Experimente online!

Gato de negócios
fonte
1

Utilitários Bash + Unix, 44 bytes

bc<<<`seq "-fx=%.f^$2;s+=($1%%x==0)*x;" $1`s

Experimente online!

Execuções de teste:

for x in '40320 1' '40320 2' '40320 3' '40320 4' '40320 5' '40320 6' '40320 7' '40320 8' '46656 1' '46656 2' '46656 3' '46656 4' '46656 5' '46656 6' '46656 7' '1 1' '1 2' '1 3' '1 12' ; do echo -n "$x "; ./sumpowerdivisors $x; done

40320 1 159120
40320 2 850
40320 3 73
40320 4 17
40320 5 33
40320 6 65
40320 7 129
40320 8 1
46656 1 138811
46656 2 69700
46656 3 55261
46656 4 1394
46656 5 8052
46656 6 47450
46656 7 1
1 1 1
1 2 1
1 3 1
1 12 1
Mitchell Spector
fonte
1

Python , 56 bytes

lambda n,k:sum(j*(j**k**-1%1==n%j)for j in range(1,n+1))

Experimente online!

Bastante direto. A única coisa digna de nota é que j**k**-1%1sempre retorna um ponto flutuante em [0,1) enquanto n%jsempre retorna um número inteiro não negativo; portanto, eles só podem ser iguais se ambos forem 0 .

Dennis
fonte
1

Lote, 138 bytes

@set s=n
@for /l %%i in (2,1,%2)do @call set s=%%s%%*n
@set/at=n=0
:l
@set/an+=1,p=%s%,t+=p*!(%1%%p)
@if %p% lss %1 goto l
@echo %t%

Como o Lote não tem um operador de energia, estou abusando set/acomo uma forma de eval. Muito lento quando k=1. A aritmética de número inteiro de 32 bits limita os valores suportados de ne k:

           n   k
  (too slow)   1
 <1366041600   2
 <1833767424   3
 <2019963136   4
 <2073071593   5
 <1838265625   6
 <1801088541   7
 <1475789056   8
 <1000000000   9
 <1073741824  10
 <1977326743  11
  <244140625  12
 <1220703125  13
  <268435456  14
 <1073741824  15
   <43046721  16
  <129140163  17
  <387420489  18
 <1162261467  19
    <1048576  20
           ...
 <1073741824  30
Neil
fonte
0

R, 28 bytes diretos, 43 bytes para função

se n, k na memória:

sum((n%%(1:n)^k==0)*(1:n)^k)

para uma função:

r=function(n,k)sum((n%%(1:n)^k==0)*(1:n)^k)
Zahiro Mor
fonte