Faça engenharia reversa da sequência N-Bonacci

15

EDIT: Vou aceitar uma resposta segunda-feira, 15/02/2016. Que os bytes estejam sempre a seu favor!

No desafio "Imprima a sequência N-Bonacci" , o @DJMcGoathem descreve as seqüências N-bonacci, em que os números N anteriores são somados, em vez dos 2 tradicionais da sequência Fibonacci ( denominada "sequência duo nacci"). Ele, então, pediu para tomar duas entradas, X e N, em seguida, a saída X th N número -nacci.

Eu proponho o oposto.
Dada uma sequência, produza da qual N- nacci é um subconjunto. Eu digo "subconjunto de" porque:

  • A) essas seqüências são infinitas
  • B) se for dado o início da sequência, você poderá apenas contar o número de 1s iniciais

No caso de pertencer a várias seqüências N- nacci, escolha a mais baixa.
No caso de não pertencer a nenhuma sequência N-nacci , seu programa poderá fazer outra coisa senão imprimir algo que possa ser confundido com saída. Esses comportamentos incluem (mas não estão limitados a): loop infinito, erro, falha, excluir-se (* tosse * vigília * tosse *) ou criar um buraco negro (desde que esse buraco negro não produza nada que possa ser confundido com saída válida).
Para esse desafio, essas seqüências começam com 1. Isso significa que qualquer sequência N- nacci começa com N -s. Além disso, Ndeve ser um número inteiro positivo. Portanto, não -1- nacci, etc.

Casos de teste:

1,1,1 -> 1
49, 97 -> 7
55, 89, 144 -> 2
1 -> 1
6765 -> 2
12, 23, 45, 89 -> 12
100, 199 -> 100
Cyoce
fonte
1
create a black hole (as long as this black hole does not produce anything that could be mistaken for valid output).Nossa, as espirais do buraco negro estão convergindo para a proporção áurea! Ele deve ser válido saída para uma seqüência duoacci!
Conor O'Brien
1
@ CᴏɴᴏʀO'Bʀɪᴇɴ Pode ser uma bela proporção áurea, mas NÃO chegue perto do buraco negro! youtube.com/watch?v=TTUQyEr-sg0
Nível River St
1
Oh meu, isso é muito mais difícil do que eu pensava inicialmente ...
GamrCorps
@ mbomb007 qual é a diferença entre números inteiros positivos e números naturais?
Não que Charles seja o dia
1
@ mbomb007 ah. Eu pensei que 1 era o primeiro número natural. Eu devo ter pensado em contar números
Não que Charles seja o dia

Respostas:

7

Ruby, 94

Estou surpreso com o quão longe eu fui capaz de jogar isso dentro do mesmo algoritmo! Comecei com mais de 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
    }
}
Não que Charles
fonte
Como x=[1]*(s+z=a.size)funciona exatamente?
Cyoce 13/02/16
@ Cyy If n == 1, então nunca aumentaremos, então precisamos de uma matriz de 1, por mais longa que seja a entrada. Se n > 1, então precisamos de pelo menos n1 para a sequência. Então, s+a.sizecobre n == 1qualquer comprimento de a, e cobre o início de qualquer outra sequência, para que possamos começar a adicionar sdígitos da bateria. Isso faz sentido?
Não é que Charles
@Cyoce e se você está fazendo uma pergunta diferente, em Ruby, [1]*numberfornece uma matriz de 1's com comprimento number. Assim, x=[1]*(s+z=a.size)atribui a.sizea e z, em seguida, atribui a xuma matriz com o comprimento de 1 s+z.
Não é que Charles
3

Python 2, 176 bytes

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;

Observe que isso requer entrada neste formato:

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

ao invés de

1, 1, 2, 3...

Solução bastante simples, apenas para fazer as coisas rolarem. Vou trabalhar mais no golfe assim que alguém responder. Isso usa uma versão ligeiramente modificada do gerador N-Bonnaci da resposta de @ Data , portanto, adota- o. Então, para cada N-Bonnaci no intervalo da entrada, verifica se a entrada é uma subsequência dela.

DJMcMayhem
fonte
tente as mesmas sugestões que eu lhe dei: mude f.appendparaf+=
Cyoce 02/02
@Cyoce oh duh. Não acredito que perdi algo tão básico. fp
DJMcMayhem
O rastreamento é ;necessário?
Cyoce
1

Lua, 324 323 bytes

Quando vejo outra submissão, sinto que há algo errado com meu código ... Mas lembro que é Lua e não há todas essas funcionalidades sofisticadas: '(

Foi muito divertido, me levou algum tempo, na verdade.

Edit: Salvo 1 byte com um truque simples: usando um ::label::+ em goto labelvez de um loop infinito feito com 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 explicações

Lua não tem como definir um conjunto, subconjunto ou mesmo verificar se uma matriz / tabela contém um valor sem usar seu índice / chave. É por isso que decidi remover elementos da matriz que tomo como parâmetro. é assim que mantenho registros de quais elementos já foram computados e se foram correspondentes.

  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

Você pode experimentar o Lua online e copiar / colar o seguinte exemplo de código para executar alguns testes. Como essa função sai quando encontra a resposta (loop infinito caso contrário), você terá que alterar o índice de test[]usado (não esqueça que lua é 1-indexado :)).

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