Somma i poteri a n


14

Indicazioni

Scrivi un programma che, dato un numero intero di input n ( n >= 0), genera il numero intero positivo più piccolo m dove:

  • n = a[1]^b[1] + a[2]^b[2] + a[3]^b[3] + ... + a[k]^b[k]
  • ae bsono sequenze finite della stessa lunghezza
  • tutti gli elementi di asono minori dim
  • tutti gli elementi di bsono minori dim
  • tutti gli elementi di asono diversi e interia[x] >= 0
  • tutti gli elementi di bsono diversi e interib[x] >= 0
  • a[x]e b[x]non sono entrambi 0 (poiché 0 ^ 0 è indeterminato)

Questo è , quindi vince meno byte.

Esempi

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

Come possiamo creare una sequenza di numeri interi non negativi che abbiano una somma non infinita?
feersum

Inoltre, il primo caso non ha senso perché sarebbe sufficiente una somma con 0 termini.
feersum

@feersum Non capisco bene la tua domanda. La mia soluzione a questo è una ricerca della forza bruta di tutte le combinazioni dove m<2poi m<3poi m<4ecc. Fino a quando non trovo una somma uguale n. Inoltre, ho pensato di avere la somma per 0essere senza termini, ma allora qual è l'output? m>?
kukac67,

1
Per sequenze finite, di solito faresti qualcosa del genere n = a[1]^b[1] + a[2]^b[2] + ... + a[k]^b[k].
Volatilità del

1
Bella domanda Solo un cavillo sul primo caso di test: ae bsono sequenze finite di lunghezza 0, quindi non esiste un numero intero mche non soddisfi i vincoli e poiché non esiste un numero intero più piccolo, la risposta non è definita. Le possibili soluzioni sarebbero di chiedere il numero naturale più piccolo m(nel qual caso dovresti cambiare lì la risposta prevista 0) o il numero intero positivo più piccolo m.
Peter Taylor,

Risposte:


2

GolfScript (59 caratteri)

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

Demo online

Questo utilizza la ricorsione per enumerare i valori ottenibili per un dato me cerca il primo mche funziona. È leggermente ispirato dalla risposta di xnor ma molto differente nell'implementazione.

Dissezione

~: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

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

La funzione fè una funzione ausiliaria che verifica se nonn può essere espressa come una somma di poteri con basi distinte da e esponenti da . Utilizza una strategia ricorsiva naturale:ABn deve essere diversa da zero, e proviamo ogni possibile scelta di base ed esponente e tutti devono fallire. Li rimuoviamo dagli elenchi consentiti e diminuiamo ndell'importo corrispondente.

La funzione gè la funzione principale. Cerca un mche funzioni. Mè l'insieme di valori consentiti fino a m-1. Rimuoviamo 0dagli esponenti consentiti per interrompere 0**0(che Python valuta 1) dall'utilizzo. Questo non fa male a nulla Perché 0**xè inutile 0per tutti gli altri x.


Probabilmente potresti cambiare n and all()in n*all().
GRC

@grc Ah, in realtà non hai bisogno del corto circuito perché finisce. Grazie per il miglioramento
xnor

4

Python 2, 138 byte

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])

(Grazie a @Jakube per tutti i suggerimenti)

Non ho mai imparato così tanto sul itertoolsmodulo come ho avuto da questa domanda. L'ultimo caso dura circa un minuto.

Iniziamo cercando m = 1e incrementando fino a ottenere una soluzione. Per verificare la presenza di una soluzione, ripetiamo:

  • k = 0 to m-1, dove k trova il numero di termini nella soluzione
  • Tutte le possibili combinazioni di termini (comprimendo insieme due permutazioni di sottoinsiemi [0, 1, ... m-1]con dimensioni k), quindi sommando e controllando se abbiamon

Si noti che ripetiamo kfino a m-1- anche se tecnicamente i mtermini sono possibili in totale, c'è sempre una soluzione con m-1termini in quanto 0^0non è consentita e 0^bnon contribuisce a nulla. Questo in realtà è importante perché 0^0viene trattato come 1 da Python, il che sembra un problema, ma risulta non importa!

Ecco perché.

Supponiamo che una soluzione trovata erroneamente usi 0^0come 1, ad es 3^2 + 1^1 + 0^0 = 11. Dato che generiamo solo m-1termini, ci devono essere alcuni jche non stiamo usando come base (qui j = 2). Possiamo scambiare lo 0 di base per jottenere una soluzione valida, qui 3^2 + 1^1 + 2^0 = 11.

Avevamo ripetuto a tutti m , allora avremmo potuto ottenere soluzioni errate come m = 2per n = 2, tramite 0^0 + 1^1 = 2.


Ben fatto. Puoi salvare 4 byte usando imap però. imap(pow,C,D) ... for C,D in
Jakube,

@Jakube In realtà sto esaminando il documento itertoolsmentre parliamo: PI ha già un altro salvataggio - tee.
Sp3000,

Anch'io. Inoltre, il mio errore. Perché qualcuno dovrebbe suggerire imap, quando c'è map?? -1 byte
Jakube

Il parametro predefinito per teeè già n=2. Salva 2 byte.
Jakube,

@Jakube Ahaha grazie. Questa è probabilmente la prima volta che ho mai usato mapcon più di un iterabile, e in effetti questa domanda mi fa emergere molte novità.
Sp3000,

4

GolfScript ( 90 84 byte)

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

Demo online

Dissezione

[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

Il trucco più elegante è la gestione del caso speciale per 0.


Sono davvero felice che CJam stavolta non sia molto più breve del python standard = P
flawr

@flawr, questo è GolfScript, non CJam. Probabilmente CJam può essere un po 'più breve perché ha un prodotto cartesiano integrato. E potrebbe darsi che l'idea di xnor di una funzione ricorsiva fornisca anche GolfScript più breve.
Peter Taylor,

Oh scusa, li
ho

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])

Esempio di utilizzo: p 23->6 .

Questa è una semplice ricerca della forza bruta. Per ogni elenco [0..0], [0..1], [0..2] ... [0..∞]prendere tutti i segmenti iniziali delle permutazioni (es. [0..2]: permutazioni:, [012], [102], [210], [120], [201], [021]segmenti iniziali per 1a permutazione:, [0], [01], [012]2a :, [1], [10], [102]ecc.). Per ogni combinazione di 2 di tali elenchi calcolare la somma dei poteri. Stop quando il primo è uguale a n.


dovresti usare >>=piuttosto che concatMap. sono uguali ma con gli argomenti invertiti.
orgoglioso haskeller il

@proudhaskeller: Sì, grazie!
nimi,

2

Python: 166 caratteri

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)])

Spiegazione

La funzione fcrea tutti i possibili numeri interi, che possono essere espressi come somma dei poteri dei numeri in r. Se inizia con r = [0]. Se uno di questi numeri interi è uguale a n, restituisce la lunghezza di r, altrimenti si chiama ricorsivamente con un esteso r.

Il calcolo di tutti i numeri interi, che può essere espresso come somma, viene eseguito con due loop. Il primo ciclo è il for j in r, che ci dice la lunghezza dell'espressione (2 ^ 3 + 1 ^ 2 ha lunghezza 2). L'anello interno scorre su tutte le combinazioni di permutazioni rdi lunghezza j. Per ogni calcolo della somma dei poteri.


2

JavaScript (ES6) 219 224

Funzione ricorsiva. A partire da m = 1, provo tutte le combinazioni dell'intero 1..m per le basi e 0..m per gli esponenti (0 base è inutile dato 0 ^ 0 == indefinito).
Se non viene trovata alcuna soluzione, aumentare m e riprovare.
Caso speciale per l'ingresso 0 (a mio avviso è comunque un errore nelle specifiche)

La funzione C genera ricorsivamente tutte le combinazioni da un array di una determinata lunghezza, in modo che

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

Il terzo livello everyviene utilizzato per comprimere l'array a di basi eb di esponenti (non esiste alcuna zipfunzione in JavaScript). Utilizzare everyper interrompere in anticipo quando esiste una soluzione che non utilizza tutti gli elementi nei due array.

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

Test nella console FireFox / FireBug

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

Produzione

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.