Ingeniería inversa de la secuencia de N-Bonacci [s]

15

EDITAR: aceptaré una respuesta el lunes 15/02/2016. ¡Que los bytes estén siempre a tu favor!

En su desafío "Imprima la secuencia de N-Bonacci" , @DJMcGoathem describe las secuencias de N-bonacci, en las que se suman los números N anteriores , en lugar de los 2 tradicionales de la secuencia de Fibonacci (que se dice que es la " secuencia duo nacci"). Luego pidió tomar dos entradas, X y N, y luego sacar el número X - N -nacci.

Propongo lo contrario.
Dada una secuencia, muestra de qué secuencia N -nacci es un subconjunto. Digo "subconjunto de" porque:

  • A) estas secuencias son infinitas
  • B) si se le da el inicio de la secuencia, podría contar el número de 1s iniciales

En el caso de que pueda pertenecer a múltiples secuencias de N -nacci, elija la más baja.
En el caso de que no pertenezca a ninguna secuencia de N-nacci , entonces su programa puede hacer algo más que imprimir algo que podría confundirse con la salida. Estos comportamientos incluyen (pero no se limitan a): bucle infinito, error, bloqueo, borrarse a sí mismo (* tos tos * vigilia * tos tos *), o crear un agujero negro (siempre que este agujero negro no produzca nada que pueda confundirse con una salida válida).
En aras de este desafío, estas secuencias comienzan con 1. Esto significa que cualquier secuencia N -nacci comienza con N las. Además, Ndebe ser un entero positivo. Entonces no -1 -nacci, etc.

Casos de prueba:

1,1,1 -> 1
49, 97 -> 7
55, 89, 144 -> 2
1 -> 1
6765 -> 2
12, 23, 45, 89 -> 12
100, 199 -> 100
Cyoce
fuente
1
create a black hole (as long as this black hole does not produce anything that could be mistaken for valid output).¡Mi, las espirales del agujero negro están convergiendo a la proporción dorada! ¡ Debe ser una salida válida para una secuencia duoacci!
Conor O'Brien
1
@ CᴏɴᴏʀO'Bʀɪᴇɴ Puede ser una hermosa proporción dorada, ¡pero NO te acerques al agujero negro! youtube.com/watch?v=TTUQyEr-sg0
Level River St el
1
Oh, esto es mucho más difícil de lo que originalmente pensé ...
GamrCorps
@ mbomb007 ¿cuál es la diferencia entre enteros positivos y números naturales?
No es que Charles
1
@ mbomb007 ah. Pensé que 1 era el primer número natural. Debo haber estado pensando en contar números
No es que Charles

Respuestas:

7

Rubí, 94

¡Estoy bastante sorprendido de lo lejos que he podido jugar golf con el mismo algoritmo! ¡Empecé con más 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}}

Sin golf:

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
    }
}
No es que Charles
fuente
¿Cómo x=[1]*(s+z=a.size)funciona exactamente?
Cyoce
@Cyoce If n == 1, entonces nunca incrementaremos, por lo que necesitamos una matriz de 1 sin importar la longitud de la entrada. Si n > 1, entonces necesitamos al menos n1 para la secuencia. Por lo tanto, s+a.sizecubre n == 1cualquier longitud de a, y cubre el comienzo de cualquier otra secuencia para que podamos comenzar a agregar sdígitos del bloque. ¿Tiene sentido?
No es que Charles
@Cyoce y si estás haciendo una pregunta diferente, en Ruby, [1]*numberda una matriz de 1 con longitud number. Entonces x=[1]*(s+z=a.size)asigna a.sizeaz , luego se asigna a xuna matriz de 1 de longitud s+z.
No es 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;

Tenga en cuenta que esto requiere una entrada en este formato:

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

más bien que

1, 1, 2, 3...

Solución bastante sencilla, solo para que todo funcione. Trabajaré más en jugar golf una vez que alguien más responda. Esto usa una versión ligeramente modificada del generador N-Bonnaci de la respuesta de @ Data , por lo que lo apoya. Luego, para cada N-Bonnaci en el rango de la entrada, verifica si la entrada es una subsecuencia de la misma.

DJMcMayhem
fuente
pruebe las mismas sugerencias que le di: cambiar f.appendparaf+=
Cyoce
@Cyoce oh duh. No puedo creer que me haya perdido algo tan básico. fp
DJMcMayhem
¿Es ;necesario el seguimiento ?
Cyoce
1

Lua 324323 bytes

Cuando veo otra presentación, siento que hay algo mal con mi código ... Pero luego, recuerdo que es Lua, y no hay todas estas funcionalidades elegantes: '(

Fue muy divertido, en realidad me llevó algo de tiempo.

Editar: guardado 1 byte con un simple truco: usando un ::label::+ en goto labellugar de un bucle infinito hecho 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 y explicaciones

Lua no tiene forma de definir un conjunto, subconjunto o incluso verificar si una matriz / tabla contiene un valor sin usar su índice / clave. Es por eso que he decidido eliminar elementos de la matriz que tomo como parámetro. así es como mantengo un registro de los elementos que ya se han calculado y si coinciden.

  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

Puede probar Lua en línea , y puede copiar / pegar el siguiente ejemplo de código para ejecutar algunas pruebas. Cuando esta función salga cuando encuentre la respuesta (de lo contrario, bucle infinito), tendrá que cambiar el índice de test[]utilizado (no olvide que lua tiene 1 índice :)).

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
fuente