Ingegnere inverso la sequenza N-Bonacci [s]


15

EDIT: Accetterò una risposta lunedì, 15/02/2016. Possano i byte essere sempre a tuo favore!

Nella sua sfida "Stampa la sequenza N-Bonacci" , @DJMcGoathem descrive le sequenze N-bonacci, in cui vengono sommati i precedenti numeri N , anziché i tradizionali 2 della sequenza di Fibonacci (detta " sequenza duo nacci"). Ha poi chiesto di prendere due ingressi, X e N, poi uscita la X ° N il numero -nacci.

Propongo il contrario.
Data una sequenza, emette la sequenza N- nacci di cui è un sottoinsieme. Dico "sottoinsieme di" perché:

  • A) queste sequenze sono infinite
  • B) se viene dato l'inizio della sequenza, puoi semplicemente contare il numero di 1 iniziali

Nel caso in cui potesse appartenere a più sequenze N- nacci, scegli quella più bassa.
Nel caso in cui non appartenga a nessuna sequenza N-nacci , il tuo programma potrebbe fare altro che stampare qualcosa che potrebbe essere scambiato per l'output. Questi comportamenti includono (ma non sono limitati a): ciclo infinito, errore, arresto anomalo, eliminazione di se stesso (* tosse tosse * veglia * tosse tosse *) o creazione di un buco nero (purché questo buco nero non produca nulla che possa essere confuso con output valido).
Per motivi di questa sfida, queste sequenze iniziano con 1. Si intende qualsiasi N sequenza -nacci inizia con N quelli. Inoltre, Ndeve essere un numero intero positivo. Quindi niente -1 -nacci, ecc.

Casi test:

1,1,1 -> 1
49, 97 -> 7
55, 89, 144 -> 2
1 -> 1
6765 -> 2
12, 23, 45, 89 -> 12
100, 199 -> 100

1
create a black hole (as long as this black hole does not produce anything that could be mistaken for valid output).Mio, le spirali del buco nero stanno convergendo al rapporto aureo! Essa deve essere emesso valida per una sequenza duoacci!
Conor O'Brien,

1
@ CᴏɴᴏʀO'Bʀɪᴇɴ Potrebbe essere un bellissimo rapporto aureo, ma NON andare vicino al buco nero! youtube.com/watch?v=TTUQyEr-sg0
Level River St

1
Oh mio Dio, è molto più difficile di quanto pensassi inizialmente ...
GamrCorps,

@ mbomb007 qual è la differenza tra numeri interi positivi e numeri naturali?
Non che Charles

1
@ mbomb007 ah. Pensavo che 1 fosse il primo numero naturale. Devo aver pensato di contare i numeri
Non quel Charles

Risposte:


7

Ruby, 94

Sono abbastanza sorpreso di quanto sono stato in grado di giocare a golf con lo stesso algoritmo! Ho iniziato con oltre 200!

->a{1.step.find{|s|x=[1]*(s+z=a.size)
x<<x[-s,s].inject(:+)while x.max<a.max&&s>1
x[-z,z]==a}}

Ungolfed:

l=->a{
    # ooh! a built-in infinite incrementer!
    1.step.find{|s|
        # if n == 1, z is important, otherwise s.
        x=[1]*(s+z=a.size)
        ## add the next nacci number until we hit or overshot max. 
        ## if s == 1, we don't increment, so don't bother
        x<<x[-s,s].inject(:+)while x.max<g&&s>1
        # eval to true if there's a match, false if not
        x[-z,z]==a
    }
}

Come x=[1]*(s+z=a.size)funziona esattamente?
Cyoce,

@Cyoce Se n == 1, allora non aumenteremo mai, quindi abbiamo bisogno di un array di 1 per quanto sia lungo l'input. Se n > 1, allora abbiamo bisogno di almeno n1 per la sequenza. Quindi s+a.sizecopre n == 1per qualsiasi lunghezza di a, e copre l'inizio di qualsiasi altra sequenza in modo da poter iniziare ad aggiungere scifre dalla battuta. Ha senso?
Non che Charles, il

@Cyoce e se stai facendo una domanda diversa, in Ruby, ti [1]*numberdà una serie di 1 con lunghezza number. Quindi x=[1]*(s+z=a.size)assegna a.sizea z, quindi assegna a xun array della lunghezza di 1 s+z.
Non che Charles il

3

Python 2, 176 byte

def r(n,x):i,f=n,[1]*n;exec"f+=sum(f[i-n:]),;i+=1;"*(x-n);return f
l=input()
m=max(l)+len(l)
for i in range(1,m):
 if any(l==r(i,m)[b:b+len(l)]for b in range(m)):print i;break;

Si noti che ciò richiede input in questo formato:

[1, 1, 2, 3...]

piuttosto che

1, 1, 2, 3...

Soluzione abbastanza semplice, solo per far rotolare le cose. Lavorerò di più sul golf una volta che qualcun altro risponde. Questo utilizza una versione leggermente modificata del generatore N-Bonnaci dalla risposta di @ Data , quindi propaga per lui. Quindi, per ogni N-Bonnaci nel raggio di azione dell'input, controlla se l'input ne costituisce una sottosequenza.


prova gli stessi suggerimenti che gli ho dato: cambia f.appendperf+=
Cyoce

@Cyoce oh duh. Non riesco a credere di aver perso qualcosa di così semplice. fp
DJMcMayhem

Il trailing è ;necessario?
Cyoce,

1

Lua, 324 323 byte

Quando vedo altri invii, sento che c'è qualcosa che non va nel mio codice ... Ma poi, ricordo che è Lua, e non ci sono tutte queste fantasiose funzionalità: '(

È stato molto divertente, in realtà mi ci è voluto del tempo.

Modifica: 1 byte salvato con un semplice trucco: usando un ::label::+ goto labelinvece un ciclo infinito fatto con while''.

function f(l)c=2 y,z=table.remove,os.exit while(l[1]<2)do y(l,1)if(#l<1)then print(1)z()end end ::q:: a={}for i=1,c do a[i]=1 end b={}for i=1,#l do b[i]=l[i]end while(a[#a]<b[1])do x=0 for i=(#a-c+1>0 and #a-c+1 or 1),#a do x=x+a[i]end a[#a+1]=x if a[#a]==b[1]then y(b,1)end if #b<1 then print(c)z()end end c=c+1 goto q end

Ungolfed e spiegazioni

Lua non ha modo di definire un set, un sottoinsieme o persino verificare se un array / tabella contiene un valore senza usare il suo indice / chiave. Ecco perché ho deciso di rimuovere elementi dall'array che prendo come parametro. è così che tengo traccia di quali elementi sono già stati calcolati e se corrispondono.

  function f(l)
  c=2
  y,z=table.remove,os.exit           -- Create pointers on table.remove and os.exit
                                     -- saves a total of 9 bytes
  while(l[1]<2)                      -- loop used to remove leading 1
  do 
    y(l,1)
    if(#l<1)                         -- we also check if it was a 1-only array
    then 
      print(1)                       -- if so, we print 1 and exit
      z()
    end 
  end

  ::q::                              -- label q, start of the infinite loop
    a={}for i=1,c do a[i]=1 end      -- fill an array with c 1s
    b={}for i=1,#l do b[i]=l[i]end   -- copy the sequence array
    while(a[#a]<b[1])                -- while max(a)<min(b)
    do
      x=0 for i=(#a-c+1>0            -- iterate from index a.length-c to
                    and #a-c+1       -- to a.length
                    or 1),#a 
      do 
        x=x+a[i]                     -- summing a's elements
      end
      a[#a+1]=x                      -- append x to a
      if a[#a]==b[1]then y(b,1)end   -- if x is equal ot a member of the sequence
                                     -- remove it
      if #b<1 then print(c)z()end    -- if b is empty, it means the subset is in a
                                     -- we print c and exit
    end                              -- else we loop again
    c=c+1                            -- with c+1
  goto q                             -- return to the start of this block
end

Puoi provare Lua online e copiare / incollare il seguente esempio di codice per eseguire alcuni test. Poiché questa funzione termina quando trova la risposta (altrimenti un ciclo infinito), dovrai cambiare l'indice di test[]usato (non dimenticare che lua è 1-indicizzato :)).

function f(l)c=2 y,z=table.remove,os.exit while(l[1]<2)do y(l,1)if(#l<1)then print(1)z()end end ::q:: a={}for i=1,c do a[i]=1 end b={}for i=1,#l do b[i]=l[i]end while(a[#a]<b[1])do x=0 for i=(#a-c+1>0 and #a-c+1 or 1),#a do x=x+a[i]end a[#a+1]=x if a[#a]==b[1]then y(b,1)end if #b<1 then print(c)z()end end c=c+1 goto q end

test={{1,1,1},
{49, 97},
{55, 89, 144},
{1},
{6765},
{12, 23, 45, 89},
{100, 199}}

print(f(test[1]))
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.