Soma os poderes para n

14

instruções

Escreva um programa que, dado um número inteiro de entrada n ( n >= 0), produz o menor número inteiro positivo m onde:

  • n = a[1]^b[1] + a[2]^b[2] + a[3]^b[3] + ... + a[k]^b[k]
  • ae bsão seqüências finitas do mesmo comprimento
  • todos os elementos de asão menores quem
  • todos os elementos de bsão menores quem
  • todos os elementos de asão diferentes e inteirosa[x] >= 0
  • todos os elementos de bsão diferentes e inteirosb[x] >= 0
  • a[x]e b[x]não são ambos 0 (já que 0 ^ 0 é indeterminado)

Isso é , e o menor número de bytes vence.

Exemplos

In 0 -> Out 1
Possible Sum: 

In 1 -> Out 2
Possible Sum: 1^0

In 2 -> Out 3
Possible Sum: 2^1

In 3 -> Out 3
Possible Sum: 2^1 + 1^0

In 6 -> Out 4
Possible Sum: 2^2 + 3^0 + 1^1

In 16 -> Out 5
Possible Sum: 2^4

In 17 -> Out 4
Possible Sum: 3^2 + 2^3

In 23 -> Out 6
Possible Sum: 5^1 + 3^0 + 2^4 + 1^3

In 24 -> Out 5
Possible Sum: 4^2 + 2^3

In 27 -> Out 4
Possible Sum: 3^3

In 330 -> Out 7
Possible Sum: 6^1 + 4^3 + 3^5 + 2^4 + 1^0
kukac67
fonte
Como devemos fazer uma sequência de números inteiros únicos e não negativos que possuam uma soma não infinita?
feersum
Além disso, o primeiro caso não faz sentido porque uma soma com 0 termos seria suficiente.
precisa saber é
@feersum Não entendi bem sua pergunta. Minha solução para isso é uma busca por força bruta de todas as combinações, onde m<2então m<3então m<4etc. até encontrar uma soma igual n. Além disso, pensei em ter a soma 0como sem termos, mas qual é o resultado? m>?
precisa saber é o seguinte
1
Para seqüências finitas, você normalmente faria algo assim n = a[1]^b[1] + a[2]^b[2] + ... + a[k]^b[k].
Volatilidade
1
Boa pergunta. Apenas uma queixa no primeiro caso de teste: ae bsão seqüências finitas de comprimento 0, então não há um número inteiro mque não satisfaça as restrições e, como não há um número inteiro menor, a resposta não é definida. As possíveis correções seriam pedir o menor número natural m(nesse caso, você deve alterar a resposta esperada para lá 0) ou o menor número inteiro positivo m.
Peter Taylor

Respostas:

2

GolfScript (59 caracteres)

~:T),{),.0{2$0-{2${{4$2$^}2*@3$\?4$+f~}%\;~}%+\;\;}:f~T&}?)

Demonstração online

Isso usa recursão para enumerar os valores alcançáveis ​​para um dado me pesquisa o primeiro mque funciona. É levemente inspirado pela resposta do xnor, mas bastante diferente na implementação.

Dissecação

~:T                  # Evaluate input and store in T (for Target)
),{                  # Search [0 1 ... T] for the first m which matches a predicate
  ),.0               #   Push [0 ... m] to the stack twice and then 0
                     #   Stack holds: possibleAs possibleBs sum
  {                  #   Define the recursive function f
    2$0-{            #     Map over A in possibleAs (except 0)
      2${            #       Map over B in possibleBs (except 0)
        {4$2$^}2*    #         Duplicate respective possibles and remove selected values
        @3$\?4$+     #         Compute sum' = sum + A^B
        f            #         Recursive call gives an array [sums]
        ~            #         Push the sums to the stack individually
        }%           #       End map: this collects the sums into a combined array
      \;             #       Pop A, leaving just the combined [sums] inside the map
      ~              #       Repeat the trick: push to the stack individually
    }%               #     End map, collecting into a combined array
                     #     Stack now holds: possibleAs possibleBs sum [sums]
    +                #     Include the original sum in the array of reachable sums
    \;\;             #     Pop possibleAs and possibleBs
  }:f                #   End function definition
  ~                  #   Evaluate the function
  T&                 #   Test whether the sums contain T
}?                   # End search
)                    # Increment to get m
Peter Taylor
fonte
6

Python, 120

f=lambda n,A,B:n*all(f(n-a**b,A-{a},B-{b})for a in A for b in B)
g=lambda n,m=1,M={0}:f(n,M-{0},M)and g(n,m+1,M|{m})or m

A função fé uma função auxiliar que verifica se nãon pode ser expressa como uma soma de potências com bases distintas e expoentes de . Ele usa uma estratégia recursiva natural: deve ser diferente de zero, e tentamos todas as opções possíveis de base e expoente e todas elas precisam falhar. Nós os removemos das listas permitidas e diminuímos na quantidade correspondente.ABnn

A função gé a função principal. Ele procura por um mque funcione. Mé o conjunto de valores permitidos até m-1. Removemos 0dos expoentes permitidos para parar 0**0(que o Python avalia como 1) de serem usados. Isso não machuca nada, porque 0**xé inútil 0para todos os outros x.

xnor
fonte
Você provavelmente poderia mudar n and all()para n*all().
grc
@ GRC Ah, na verdade, você não precisa de um curto-circuito, porque acaba se esgotando. Obrigado pela melhoria.
Xnor
4

Python 2, 138 bytes

from itertools import*
S=lambda n,m=0,R=[]:m*any(n==sum(map(pow,*C))for k in R for C in product(*tee(permutations(R,k))))or S(n,m+1,R+[m])

(Obrigado a @Jakube por todas as dicas)

Nunca aprendi tanto sobre o itertoolsmódulo quanto aprendi com essa pergunta. O último caso leva cerca de um minuto.

Começamos pesquisando m = 1e incrementando até obtermos uma solução. Para verificar uma solução, iteramos sobre:

  • k = 0 to m-1, onde ké o número de termos na solução
  • Toda combinação possível de termos (fechando duas permutações de subconjuntos de [0, 1, ... m-1]com tamanho k), somando e verificando se temosn

Observe que iteramos katé m-1- mesmo que os mtermos tecnicamente sejam possíveis no total, sempre há uma solução com m-1termos que 0^0não são permitidos e 0^bnão contribui com nada. Isso é realmente importante porque 0^0é tratado como 1 pelo Python, o que parece ser um problema, mas acaba não importando!

Aqui está o porquê.

Suponha que uma solução encontrada erroneamente use 0^0como 1, por exemplo 3^2 + 1^1 + 0^0 = 11. Como geramos apenas m-1termos, deve haver alguns jque não estamos usando como base (aqui j = 2). Podemos trocar a base 0 para jobter uma solução válida aqui 3^2 + 1^1 + 2^0 = 11.

Se tivéssemos iterado todos os mtermos, poderíamos ter obtido soluções incorretas como m = 2para n = 2, via 0^0 + 1^1 = 2.

Sp3000
fonte
Agradável. Você pode salvar 4 bytes usando o imap. imap(pow,C,D) ... for C,D in
Jakube 17/01/15
@Jakube Na verdade, estou pesquisando o documento itertoolsenquanto falamos: PI já tem outra economia - tee.
SP3000
Eu também. Além disso, meu erro. Por que alguém sugeriria imap, quando houver map? -1 byte
Jakube
O parâmetro padrão para teejá é n=2. Salva 2 bytes.
Jakube 17/01/15
@Jakube Ahaha thanks. Esta é provavelmente a primeira vez que eu já usei mapcom mais de uma iterável e, de fato, essa pergunta trouxe muitas novidades para mim.
SP3000
4

GolfScript ( 90 84 bytes)

[0.,.]](~:T),(+{:x;{:|2,{:c)|=x),^{c[1$x]=:A^x^:-;[|~-+@A-?+@A+@]}%}/+~}%.[]*T&}?)\;

Demonstração online

Dissecação

[0.,.]             # Base case: [sum As Bs] is [0 [] []]
](~:T              # Collect it in an array of cases; fetch parameter, eval, store in T.
),(+               # Create array [1 2 ... T 0]. Putting 0 at the end means that it won't
                   # be reached except when T is 0, and nicely handles that special case.
{                  # Loop over the values from that array...
  :x;              #   ...assigning each in turn to x (and popping it from the stack)
  {                #   Stack holds array of [sum As Bs] cases; map them...

    :|             #     Store [sum As Bs] in |
    2,{:c          #     For c in [0 1]...
      )|=x),^      #       Get [0 1 ... x]^ either As or Bs, depending on c
      {            #       Map these legal new As or Bs respectively...
        c[1$x]=:A  #         Work out which of that value or x is the new A
        ^x^:-;     #         And the other one is the new B
        [          #         Begin gathering in an array
          |~       #           Push sum As Bs to the stack
          -+       #           Add - to Bs to get Bs'
          @A-?+    #           Rotate sum to top and add A^- to get sum'
          @A+      #           Rotate As to top and add A to get As'
          @        #           Final rotation to put elements in the right order
        ]          #         Gather in array [sum' As' Bs']
      }%           #       End map
    }/             #     End for
    +~             #     Push all the elements corresponding to x^B and A^x on to the stack
  }%               #   End map, collecting the untouched [sum As Bs] and all the new
                   #   [sum' As' Bs'] arrays into a new array of reached cases.
  .[]*T&           #   Flatten a copy of that array and filter to values equal to T.
                   #   This gives a truthy value iff we've found a way to make T.
}?                 # Loop until we get a truthy value, and push the corresponding x
)\;                # Increment to get the value of m and discard the array of cases

O truque mais elegante é o tratamento do caso especial 0.

Peter Taylor
fonte
Estou muito feliz que CJam é desta vez não soo muito mais curto do que o padrão python = P
flawr
Flawr @, este é GolfScript, não CJam. O CJam provavelmente pode ser um pouco mais curto porque possui um built-in para produtos cartesianos. E pode ser que a ideia do xnor de uma função recursiva também ofereça um GolfScript mais curto.
Peter Taylor
Oh, desculpe, apenas confundiu =)
flawr
4

Haskell, 143 130

import Data.List
p n=head$[1..]>>=(\m->[m|let x=permutations[0..m-1]>>=inits,a<-x,b<-x,sum(zipWith(\x y->x^y*signum(x+y))a b)==n])

Exemplo de uso: p 23-> 6.

Esta é uma pesquisa simples de força bruta. Para todas as listas, [0..0], [0..1], [0..2] ... [0..∞]pegue todos os segmentos iniciais das permutações (por exemplo, [0..2]: permutações:, [012], [102], [210], [120], [201], [021]segmentos iniciais da 1ª permutação: [0], [01], [012]2ª: [1], [10], [102]etc.). Para cada combinação de 2 dessas listas, calcule a soma dos poderes. Pare quando o primeiro for igual a n.

nimi
fonte
você deve usar em >>=vez de concatMap. eles são iguais, mas com os argumentos invertidos.
orgulhoso haskeller
@proudhaskeller: Sim, obrigado!
nimi
2

Python: 166 caracteres

from itertools import*;p=permutations
f=lambda n,r=[0]:any(n==sum(map(lambda x,y:(x+y>0)*x**y,a,b))for j in r for a,b in product(p(r,j),p(r,j)))*1or 1+f(n,r+[len(r)])

Explicação

A função fcria todos os números possíveis, que podem ser expressos como a soma das potências de números em r. Se começa com r = [0]. Se qualquer um desses números inteiros for igual a n, ele retornará o comprimento de r, caso contrário, ele se chamará recursivamente com um estendido r.

O cálculo de todos os números inteiros, que podem ser expressos como soma, é feito com dois loops. O primeiro loop é ofor j in r , que nos diz o tamanho da expressão (2 ^ 3 + 1 ^ 2 tem comprimento 2). O loop interno itera sobre todas as combinações de permutações rde comprimento j. Para cada eu calculo a soma dos poderes.

Jakube
fonte
2

JavaScript (ES6) 219 224

Função recursiva. Começando com m = 1, tento todas as combinações de número inteiro 1..m para bases e 0..m para expoentes (a base 0 é inútil, dado 0 ^ 0 == indefinido).
Se nenhuma solução for encontrada, aumente me tente novamente.
Caso especial para a entrada 0 (na minha opinião, isso é um erro nas especificações de qualquer maneira)

A função C gera recursivamente todas as combinações de uma matriz de determinado comprimento, para que

C(3, [1,2,3]) --> [[3,2,1], [3,1,2], [2,3,1], [2,1,3], [1,3,2], [1,2,3]]

O terceiro nível everyé usado para compactar a matriz a de bases eb de expoentes (não há zipfunção no JavaScript). Usando everypara parar cedo quando houver uma solução que não esteja usando todos os elementos nas duas matrizes.

F=(n,j=1,k=[],
  C=(l,a,o=[],P=(l,a,i=l)=>{
    for(l||o.push(a);i--;)
      e=[...a],P(l-1,e.concat(e.splice(i,1)))
  })=>P(l,a)||o
)=>n&&C(k.push(j++),k)[E='every'](a=>C(j,[0,...k])[E](b=>a[E](x=>t-=Math.pow(x,b.pop()),t=n)))
?F(n,j,k):j

Teste no console do FireFox / FireBug

;[0,1,2,3,6,16,17,23,24,27,330].map(x=>[x,F(x)])

Resultado

[[0, 1], [1, 2], [2, 3], [3, 3], [6, 4], [16, 5], [17, 4], [23, 6], [ 24, 5], [27, 4], [330, 7]]

edc65
fonte