Imprime la secuencia de N-bonacci


54

Esto no es muy conocido, pero lo que llamamos la secuencia de Fibonacci, también conocida como

1, 1, 2, 3, 5, 8, 13, 21, 34...

en realidad se llama la secuencia de Duonacci . Esto se debe a que para obtener el siguiente número, sumas los 2 números anteriores. También está la secuencia Tribonacci ,

1, 1, 1, 3, 5, 9, 17, 31, 57, 105, 193, 355, 653, 1201...

porque el siguiente número es la suma de los 3 números anteriores. Y la secuencia de Quadronacci

1, 1, 1, 1, 4, 7, 13, 25, 49, 94, 181, 349, 673...

Y la favorita de todos, la secuencia de Pentanacci :

1, 1, 1, 1, 1, 5, 9, 17, 33, 65, 129...

Y la secuencia de Hexanacci , la secuencia de Septanacci , la secuencia de Octonacci , y así sucesivamente hasta la secuencia de N-Bonacci.

La secuencia de N-bonacci siempre comenzará con N 1 seguidos.

El reto

Debe escribir una función o programa que tome dos números N y X , e imprima los primeros números X N-Bonacci. N será un número entero mayor que 0, y puede asumir con seguridad que ningún número de N-Bonacci excederá el tipo de número predeterminado en su idioma. La salida puede estar en cualquier formato legible por humanos, y puede tomar la entrada de cualquier manera razonable. (Argumentos de línea de comando, argumentos de función, STDIN, etc.)

Como de costumbre, este es Code-golf, por lo que se aplican las lagunas estándar y gana la respuesta más corta en bytes.

Muestra IO

#n,  x,     output
 3,  8  --> 1, 1, 1, 3, 5, 9, 17, 31
 7,  13 --> 1, 1, 1, 1, 1, 1, 1, 7, 13, 25, 49, 97, 193
 1,  20 --> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
 30, 4  --> 1, 1, 1, 1       //Since the first 30 are all 1's
 5,  11 --> 1, 1, 1, 1, 1, 5, 9, 17, 33, 65, 129

1
Hombre, tuve esta idea hace un tiempo y nunca pude escribirla.
Morgan Thrapp

99
My vote button == your avatar
ETHproductions

¿No sería 3-bonacci 1, 1, 2, 4, 7como la tercera posición 0 + 1 + 1? ... y uno con los otros?
Paraguas

1
@umbrella No, el tribonacci comienza con 3 1s. Vea mi edición para aclarar este punto.
DJMcMayhem

Respuestas:


23

Boolfuck, 6 bytes

,,[;+]

Puede asumir con seguridad que ningún número de N-Bonacci excederá el tipo de número predeterminado en su idioma.

El tipo de número predeterminado en Boolfuck es un poco. Suponiendo que esto también se extiende a los números de entrada N y X, y dado que N> 0, solo hay dos entradas posibles: 10 (que no genera nada) y 11 (que genera 1).

,lee un poco en la ubicación de memoria actual. N se ignora como debe ser 1. Si X es 0, []se omite el cuerpo del bucle (rodeado por ). Si X es 1, se emite y luego se voltea a 0 para que el ciclo no se repita.


44
¿No hay una escapatoria estándar EXACTAMENTE como esta?
Stan Strum

1
@StanStrum ¿De antes o después de esta respuesta?
user253751

2
Creo que llegó antes, déjame verlo ... Meta Link ; La primera revisión fue el 31 de enero de 2016 a las 13:44. Wow, no importa! Estuve dos días libre. Aunque, para ser terco, la última edición para esto fue el 31 de enero de 2016 a las 16:06. Soooooo sí, está bien en mi libro
Stan Strum

9

Python 2, 79 bytes

n,x=input()
i,f=0,[]
while i<x:v=[sum(f[i-n:]),1][i<n];f.append(v);print v;i+=1

Pruébalo en línea


Intente reemplazar la última línea conexec"v=[sum(f[i-n:]),1][i<n];f+=[v];print v;i+=1;"*x
Cyoce

8

Pyth, 13

<Qu+Gs>QGEm1Q

Banco de pruebas

Toma entrada nueva línea separada, con nprimero.

Explicación:

<Qu+Gs>QGEm1Q  ##  implicit: Q = eval(input)
  u      Em1Q  ##  read a line of input, and reduce that many times starting with
               ##  Q 1s in a list, with a lambda G,H
               ##  where G is the old value and H is the new one
   +G          ##  append to the old value
     s>QG      ##  the sum of the last Q values of the old value
<Q             ##  discard the last Q values of this list

1
Wow, eso fue rápido. ¡Apenas tuve tiempo de cerrar mi navegador antes de que ya publicaras esto!
DJMcMayhem

5

Haskell, 56 bytes

g l=sum l:g(sum l:init l)
n#x|i<-1<$[1..n]=take x$i++g i

Ejemplo de uso: 3 # 8-> [1,1,1,3,5,9,17,31].

Cómo funciona

i<-1<$[1..n]           -- bind i to n copies of 1
take x                 -- take the first x elements of
       i++g i          -- the list starting with i followed by (g i), which is
sum l:                 -- the sum of it's argument followed by
      g(sum l:init l)  -- a recursive call to itself with the the first element
                       -- of the argument list replaced by the sum

¿No debería ser eso en tail llugar de init l?
orgulloso Haskeller

@proudhaskeller: no importa. Mantenemos los últimos nelementos en la lista. No hay diferencia entre eliminar desde el final y agregar al frente y viceversa, es decir, eliminar desde el frente y agregar al final, porque la lista inicial está compuesta solo por 1s.
nimi

Oh ya entiendo. Esa es una forma ingeniosa para reemplazar ++[]por :!
orgulloso Haskeller

@proudhaskeller: sí, ¡exactamente!
nimi

5

Python 2, 55 bytes

def f(x,n):l=[1]*n;exec"print l[0];l=l[1:]+[sum(l)];"*x

Rastrea una nventana de longitud de la secuencia en la lista l, actualizada agregando la suma y eliminando el primer elemento. Imprime el primer elemento cada iteración para xiteraciones.

Un enfoque diferente de almacenar todos los elementos y sumar los últimos nvalores dio la misma longitud (55).

def f(x,n):l=[1]*n;exec"l+=sum(l[-n:]),;"*x;print l[:x]

5

Javascript ES6 / ES2015, 107 97 85 80 bytes

Gracias a @ user81655, @Neil y @ETHproductions por guardar algunos bytes


(i,n)=>eval("for(l=Array(i).fill(1);n-->i;)l.push(eval(l.slice(-i).join`+`));l")

pruébalo en línea


Casos de prueba:

console.log(f(3,  8))// 1, 1, 1, 3, 5, 9, 17, 31
console.log(f(7,  13))// 1, 1, 1, 1, 1, 1, 1, 7, 13, 25, 49, 97, 193
console.log(f(5,  11))// 1, 1, 1, 1, 1, 5, 9, 17, 33, 65, 129

1
Agradable. Un par de consejos de golf: forsiempre es mejor que while, x.split('')-> [...x], ~~a-> +a, n-=1-> n--, si encierra todo el cuerpo de la función evaly no necesita escribir return. También, incluso más corto que [...'1'.repeat(i)]es Array(i).fill(1)y puede quitar el ~~de ay b. Y puedes eliminar el f=.
user81655

2
Esto es lo que parece con mis consejos (85 bytes): (i,n)=>eval("for(l=Array(i).fill(1);n-->i;)l.push(l.slice(-i).reduce((a,b)=>a+b));l"). Cambié el orden de las declaraciones, combiné los argumentos n--en n-iy llos eliminé para guardar algunos bytes adicionales.
user81655

1
@ user81655 No consigo el evalahorro; (i,n)=>{for(l=Array(i).fill(1);n-->i;)l.push(l.slice(-i).reduce((a,b)=>a+b));return l}sigue siendo 85 bytes.
Neil

@Neil Parece 86 bytes para mí ...
user81655

3
l.slice(-i).reduce((a,b)=>a+b)=>eval(l.slice(-i).join`+`)
ETHproductions

4

ES6, 66 bytes

(i,n)=>[...Array(n)].map((_,j,a)=>a[j]=j<i?1:j-i?s+=s-a[j+~i]:s=i)

Lamentablemente map, no le permitirá acceder a la matriz de resultados en la devolución de llamada.


1
Guarde un byte al cursar los parámetros.
Shaggy

4

Jalea, 12 bytes

ḣ³S;
b1Ç⁴¡Uḣ

Pruébalo en línea!

Cómo funciona

b1Ç⁴¡Uḣ  Main link. Left input: n. Right input: x.

b1       Convert n to base 1.
    ¡    Call...
  Ç        the helper link...
   ⁴       x times.
     U   Reverse the resulting array.
      ḣ  Take its first x elements.


ḣ³S;     Helper link. Argument: A (list)

ḣ³       Take the first n elements of A.
  S      Compute their sum.
   ;     Prepend the sum to A.

3

C ++ 11, 360 bytes

Hola, me gusta esta pregunta. Sé que C ++ es un lenguaje muy difícil para ganar esta competencia. Pero arrojaré un centavo de cualquier manera.

#include<vector>
#include<numeric>
#include<iostream>
using namespace std;typedef vector<int>v;void p(v& i) {for(auto&v:i)cout<<v<<" ";cout<<endl;}v b(int s,int n){v r(n<s?n:s,1);r.reserve(n);for(auto i=r.begin();r.size()<n;i++){r.push_back(accumulate(i,i+s,0));}return r;}int main(int c, char** a){if(c<3)return 1;v s=b(atoi(a[1]),atoi(a[2]));p(s);return 0;}

Dejaré esto como la explicación legible del código anterior.

#include <vector>
#include <numeric>
#include <iostream>

using namespace std;
typedef vector<int> vi;

void p(const vi& in) {
    for (auto& v : in )
        cout << v << " ";
    cout << endl;
}

vi bonacci(int se, int n) {
    vi s(n < se? n : se, 1);
    s.reserve(n);
    for (auto it = s.begin(); s.size() < n; it++){
        s.push_back(accumulate(it, it + se, 0));
    }
    return s;
}

int main (int c, char** v) {
    if (c < 3) return 1;
    vi s = bonacci(atoi(v[1]), atoi(v[2]));
    p(s);
    return 0;
}

Bienvenido a Programming Puzzles y Code Golf. Esta es una buena respuesta, sin embargo, he notado que tiene muchos espacios en blanco y nombres de variables y funciones que tienen más de 1 carácter. Tal como está, esta es una buena versión legible de su código, pero debe agregar una versión de golf. Cuando lo hagas, te daré un voto a favor, pero hasta que se juegue, no lo haré.
wizzwizz4

@ wizzwizz4 Hola, agregué una versión de golf del código anterior. Dejé el código sin golf para que la gente vea cómo lo hice. Además me gusta leer una función bonacci que devuelve vi que todavía suena como vibonacci. Siento que no debería acortar la función principal porque el estándar standardar exige usar int main (int, char **) como punto de entrada del programa. Además, creo que todas las variables tienen una longitud máxima de 1 carácter y se eliminan todos los espacios en blanco no significativos.
hetepeperfan

3
Esto no es código: "cumplir con los estándares". Este es el código de golf . Manipulamos y aprovechamos nuestros idiomas. Si alguna variable es ints, elimine el int. Si se llama a alguna función foo, llámela f. Sé brutal ignore el estándar y explote el compilador. Así es como juegas al golf.
wizzwizz4

Los juegos de palabras y el código agradable pertenecen solo al código no golfizado . Pero siéntase libre de mantenerlos allí; En realidad, se recomienda. Pero sé muy, muy malo con el compilador cuando juegues tu código. Hazlo lo más pequeño posible sin importar qué . (¡Ah, y aquí está el +1 que prometí!)
wizzwizz4

@ wizzwizz4 ¿Es válido eliminar "int"? Pensé que int implícito no se ejecutará.
DJMcMayhem

3

Haskell , 47 bytes

q(h:t)=h:q(t++[h+sum t])
n?x=take x$q$1<$[1..n]

Pruébalo en línea!

<$ podría haberse introducido en Prelude después de publicar este desafío.


Haskell , 53 bytes

n%i|i>n=sum$map(n%)[i-n..i-1]|0<1=1
n?x=map(n%)[1..x]

Pruébalo en línea!

Define la función binaria ?, utilizada como 3?8 == [1,1,1,3,5,9,17,31].

La función auxiliar %encuentra recursivamente el ielemento th de la nsecuencia -bonacci sumando los nvalores anteriores . Luego, la función ?tabula los primeros xvalores de %.


Respuesta anterior, pero ¿te refieres a "La función auxiliar %"?
Conor O'Brien el

Cambiar a los guardias se convertirá i<=nen i>n.
Ørjan Johansen

@ ØrjanJohansen También noté eso al editar, aunque mirar hacia atrás todo el método parece malo, así que podría volver a hacer todo el golf.
xnor

2

APL, 21

{⍵↑⍺{⍵,+/⍺↑⌽⍵}⍣⍵+⍺/1}

Esta es una función que toma n como argumento izquierdo y x como argumento derecho.

Explicación:

{⍵↑⍺{⍵,+/⍺↑⌽⍵}⍣⍵+⍺/1}
                   ⍺/1  ⍝ begin state: X ones    
                  +     ⍝ identity function (to separate it from the ⍵)
    ⍺{         }⍣⍵     ⍝ apply this function N times to it with X as left argument
      ⍵,               ⍝ result of the previous iteration, followed by...
        +/              ⍝ the sum of
          ⍺↑            ⍝ the first X of
            ⌽          ⍝ the reverse of
             ⍵         ⍝ the previous iteration
 ⍵↑                    ⍝ take the first X numbers of the result

Casos de prueba:

      ↑⍕¨ {⍵↑⍺{⍵,+/⍺↑⌽⍵}⍣⍵+⍺/1} /¨ (3 8)(7 13)(1 20)(30 4)(5 11)
 1 1 1 3 5 9 17 31                       
 1 1 1 1 1 1 1 7 13 25 49 97 193         
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
 1 1 1 1                                 
 1 1 1 1 1 5 9 17 33 65 129              

2

Pitón 3, 59

Ahorró 20 bytes gracias a FryAmTheEggman.

No es una gran solución, pero funcionará por ahora.

def r(n,x):f=[1]*n;exec('f+=[sum(f[-n:])];'*x);return f[:x]

Además, aquí hay casos de prueba:

assert r(3, 8) == [1, 1, 1, 3, 5, 9, 17, 31]
assert r(7, 13) == [1, 1, 1, 1, 1, 1, 1, 7, 13, 25, 49, 97, 193]
assert r(30, 4) == [1, 1, 1, 1]

2

Java, 82 + 58 = 140 bytes

Función para encontrar el número i- n - bonacci ( 82 bytes ):

int f(int i,int n){if(i<=n)return 1;int s=0,q=0;while(q++<n)s+=f(i-q,n);return s;}

Función para imprimir el primer número k n -bonacci ( 58 bytes ):

(k,n)->{for(int i=0;i<k;i++){System.out.println(f(i,n));}}

2

Cerebro-Flak , 144 124 122 bytes

-20 bytes gracias a Nitroden

Esta es mi primera respuesta Brain-Flak, y estoy seguro de que se puede mejorar. Cualquier ayuda es apreciada.

(([{}]<>)<{({}(()))}{}>)<>{({}[()]<<>({<({}<({}<>)<>>())>[()]}{})({}<><({({}<>)<>}<>)>)<>>)}{}<>{({}<{}>())}{}{({}<>)<>}<>

Pruébalo en línea!


2

Pari / GP , 46 bytes

La función generadora de la secuencia es:

(n1)xnxn+12x+11x1

(n,m)->Vec(n--/(x-(2-1/x)/x^n)-1/(x-1)+O(x^m))

Pruébalo en línea!


1

Julia, 78 bytes

f(n,x)=(z=ones(Int,n);while endof(z)<x push!(z,sum(z[end-n+1:end]))end;z[1:x])

Esta es una función que acepta dos enteros y devuelve una matriz de enteros. El enfoque es simple: genere una matriz de unos de longitud n, luego aumente la matriz agregando la suma de los nelementos anteriores hasta que la matriz tenga longitud x.

Sin golf:

function f(n, x)
    z = ones(Int, n)
    while endof(z) < x
        push!(z, sum(z[end-n+1:end]))
    end
    return z[1:x]
end

1

MATL , 22 26 bytes

1tiXIX"i:XK"tPI:)sh]K)

Esto usa la versión actual (10.2.1) del lenguaje / compilador.

Pruébalo en línea!

Algunos bytes adicionales :-( debido a un error en la Gfunción (pegar entrada; ahora corregido para la próxima versión)

Explicación

1tiXIX"      % input N. Copy to clipboard I. Build row array of N ones
i:XK         % input X. Build row array [1,2,...X]. Copy to clipboard I
"            % for loop: repeat X times. Consumes array [1,2,...X]
  t          % duplicate (initially array of N ones)
  PI:)       % flip array and take first N elements
  sh         % compute sum and append to array
]            % end
K)           % take the first X elements of array. Implicitly display

1

Perl 6 , 38 bytes

->\N,\X{({@_[*-N..*].sum||1}...*)[^X]} # 38 bytes
-> \N, \X {
  (

    {

      @_[
        *-N .. * # previous N values
      ].sum      # added together

      ||     # if that produces 0 or an error
      1      # return 1

    } ... *  # produce an infinite list of such values

  )[^X]      # return the first X values produced
}

Uso:

# give it a lexical name
my &n-bonacci = >\N,\X{…}

for ( (3,8), (7,13), (1,20), (30,4), (5,11), ) {
  say n-bonacci |@_
}
(1 1 1 3 5 9 17 31)
(1 1 1 1 1 1 1 7 13 25 49 97 193)
(1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
(1 1 1 1)
(1 1 1 1 1 5 9 17 33 65 129)

1

C, 132 bytes

El enfoque recursivo es más corto en un par de bytes.

k,n;f(i,s,j){for(j=s=0;j<i&j++<n;)s+=f(i-j);return i<n?1:s;}main(_,v)int**v;{for(n=atoi(v[1]);k++<atoi(v[2]);)printf("%d ",f(k-1));}

Sin golf

k,n; /* loop index, n */

f(i,s,j) /* recursive function */
{
    for(j=s=0;j<i && j++<n;) /* sum previous n n-bonacci values */
        s+=f(i-j);
    return i<n?1:s; /* return either sum or n, depending on what index we're at */
}

main(_,v) int **v;
{
    for(n=atoi(v[1]);k++<atoi(v[2]);) /* print out n-bonacci numbers */
        printf("%d ", f(k-1));
}

1

Casco , 9 bytes

↑§¡ȯΣ↑_B1

Pruébalo en línea!

Comienza desde el Base- 1representación de N (simplemente una lista de N unos) y ¡teratively sumas ( Σ) los últimos ( ↑_) N elementos y añade el resultado a la lista. Finalmente, toma ( ) los primeros números X en esta lista y los devuelve.





0

Perl 6, 52 ~ 72 47 ~ 67 bytes

sub a($n,$x){EVAL("1,"x$n~"+*"x$n~"...*")[^$x]}

Requiere el módulo MONKEY-SEE-NO-EVAL, debido al siguiente error:

=== ¡LO SENTIMOS! === ¡Error al compilar -e
EVAL es una función muy peligrosa! (use MONKEY-SEE-NO-EVAL para anular,
pero solo si está MUY seguro de que sus datos no contienen ataques de inyección)
en -e: 1

$ perl6 -MMONKEY-SEE-NO-EVAL -e'a(3,8).say;sub a($n,$x){EVAL("1,"x$n~"+*"x$n~"...*")[^$x]}'
(1 1 1 3 5 9 17 31)

¿Alguien sabe de una manera de desactivar el modo estricto, etc.?
andlrc

Creo que si usas un lanzamiento de Perl 6 antes de Navidad de 2015, no exige mono-see-no-eval.
Batman el


0

Jq 1.5 , 67 bytes

def C:if length>X then.[:X]else.+=[.[-N:]|add]|C end;[range(N)|1]|C

Asume la entrada proporcionada por N y X, por ejemplo

def N: 5;
def X: 11;

Expandido

def C:                        # . is current array
    if length>X               # stop when array is as long as X
    then .[:X]                # return first X elements
    else .+=[.[-N:]|add] | C  # recursively add sum of last N elements to array
    end
;
  [range(N)|1]                # initial state
| C

Pruébalo en línea!


0

J, 31 bytes

]{.(],[:+/[{.])^:(-@[`]`(1#~[))

Sin golf:

] {. (] , [: +/ [ {. ])^:(-@[`]`(1 #~ [))

explicación

Momentos divertidos con el verbo power en su forma gerundia :

(-@[`]`(1 #~ [)) NB. gerund pre-processing

Desglose en detalle:

  • ] {. ...Tome los primeros <right arg>elementos de todo esto a la derecha que hace el trabajo ...
  • <left> ^: <right>aplique el verbo <left>varias <right>veces ... donde <right>está especificado por el gerundio medio en (-@[] (1 #~ [), es decir ], es decir, el argumento derecho pasó a la función misma. Entonces que es <left>? ...
  • (] , [: +/ [ {. ])El argumento de la izquierda a la totalidad de esta frase se transforma primero por el primer gerundio, es decir, -@[. Eso significa que el argumento izquierdo de esta frase es el negativo del argumento izquierdo de la función general. Esto es necesario para que la frase [ {. ]tome los últimos elementos de la lista de retorno que estamos construyendo. Los que se suman entonces: +/. Y finalmente anexado a la misma lista de regreso: ] ,.
  • Entonces, ¿cómo se inicializa la lista de retorno? Eso es lo que logra el tercer gerundio de preprocesamiento: (1 #~ [)- repita 1 número de "argumento izquierdo" varias veces.

Pruébalo en línea!


0

Mathematica, 59 bytes

((f@#=1)&/@Range@#;f@n_:=Tr[f[n-#]&/@Range@#];f/@Range@#2)&

Probablemente querrá Clear@fentre llamadas a funciones. Los argumentos son n,x, al igual que los casos de prueba.


0

Ordenado , 36 bytes

{x,n:n^recur(*tile(x,c(1)),sum@c,x)}

Pruébalo en línea!

Explicación

{x,n:n^recur(*tile(x,c(1)),sum@c,x)}
{x,n:                              }   lambda taking parameters `x` and `n`
     n^                                take the first `n` terms of...
       recur(                     )        a recursive function
             *tile(x,c(1)),                whose seed is `x` `1`s
                           sum@c,          taking the sum of each window
                                 x         with a window size of `x`

0

Japt , 18 bytes

@ZsVn)x}gK=Vì1;K¯U

Pruébalo en línea!

Explicación:

         K=Vì1        :Start with n 1s in an array K
@      }gK            :Extend K to at least x elements by setting each new element to:
      x               : The sum of
 ZsVn                 : The previous n elements
              ;       :Then
               K¯U    :Return the first n elements of K
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.