Encuentra los patrones de Fibonacci


16

Probablemente esté familiarizado con la secuencia de Fibonacci donde los dos primeros términos son 0, 1(o a veces 1, 1) y cada término posterior es la suma de los dos anteriores. Comienza así:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

A veces, la secuencia contiene números que tienen un patrón particular que me parece interesante: la diferencia entre cualquier par de dígitos adyacentes es la misma que cualquier otro par. Por ejemplo, en la secuencia que comienza con 0, 1, el decimoctavo término es 987. 9-8=1y 8-7=1. Estoy ligeramente satisfecho

Desafío

Dados dos valores iniciales F(0)y F(1), genera cada número en la secuencia generada F(n) = F(n-1) + F(n-2)que cumple los siguientes criterios:

  • La diferencia entre cualquier par de dígitos adyacentes es la misma que cualquier otro par
  • Tiene al menos tres dígitos (los números de 1 y 2 dígitos no son interesantes para este patrón)

Entrada

  • Dos enteros no negativos menores de 10 ** 10 (10 mil millones)

Salida

  • Todos los enteros que son menores de 10 ** 10 y cumplen los criterios de la sección Desafío
  • Es aceptable generar dígitos superiores a 10 ** 10, pero no es un requisito
  • Dado que los dígitos repetidos cumplen con el patrón (p 777. Ej. ), Es posible que haya números infinitos que cumplan con los criterios, pero no se requiere que su programa salga para siempre
  • Si no existen tales enteros, envíe lo que desee siempre que no sea un número (nada, nulo, matriz vacía, mensaje de error, cara triste, etc.)
  • Si un número que coincide con el patrón aparece más de una vez en la secuencia, puede generarlo una o tantas veces como ocurra
  • Si alguna entrada cumple con los criterios, debe incluirse en la salida

Reglas

Ejemplos / Casos de prueba

Input , Output   
[1,10] , []   

[0,1] , [987]   
[2,1] , [123]   
[2,3] , [987]   

[61,86] , [147]   
[75,90] , [420]   
[34,74] , [1234]   
[59,81] , [2468]   
[84,85] , [7531]   

[19,46] , [111]   
[60,81] , [222]   
[41,42] , [333]   
[13,81] , [444]   
[31,50] , [555]   
[15,42] , [666]   
[94,99] , [777]   
[72,66] , [888]  
[3189,826] , [888888888]    

[15,3] , [159,258]   
[22,51] , [321,1357]   
[74,85] , [159,4444]   
[27,31] , [147,11111]   

[123,0] , [123,123,123,246,369]   
[111,0] , [111,111,111,222,333,555,888]
[111,222] , [111,222,333,555,888]      

[33345,692] , [987654321]   
[3894621507,5981921703] , [9876543210]
[765432099,111111111] , [111111111,876543210,987654321]   

[1976,123] , [123, 2222, 4321, 6543, 45678]   

1
Casos de prueba sugeridas: [1976, 123] -> [123, 2222, 4321, 6543, 45678], [3189, 826] -> [888888888],[33345, 692] -> [987654321]
Arnauld

@Arnauld ¡Gran descubrimiento! Me pregunto qué par inicial tiene la mayoría de los valores de salida inferiores a 10B. Cualquier cosa por encima de eso será repdigits y eso es aburrido.
Engineer Toast

@Arnauld Gracias por las correcciones de casos de prueba. En mi generador original, no incluí las entradas. Claramente extrañaba a esos dos cuando volví y los agregué.
Ingeniero Brindis

Respuestas:


9

MATL , 14 bytes

Gracias a Emigna por señalar un error, ahora corregido

`yVdd~?yD]wy+T

Bucle infinito que genera los números a medida que se encuentran.

Pruébalo en línea! Tenga en cuenta que en el intérprete en línea los resultados se muestran después del tiempo de espera de 1 minuto.

Explicación

Deje F(n)y F(n+1)denote dos términos genéricos consecutivos de la secuencia de Fibonacci. Cada iteración del ciclo comienza con la pila que contiene F(n), F(n+1)para algunos n.

`         % Do...while
  y       %   Duplicate from below. Takes the two inputs F(0), F(1) (implicitly)
          %   in the first iteration
          %   STACK: F(n), F(n+1), F(n)
  V       %   Convert to string. Let the digits of F(n) be '3579' for example
          %   STACK: F(n), F(n+1), '3579'
  d       %   Consecutive differences (of ASCII codes)
          %   STACK: F(n), F(n+1), [2 2 2]
  d       %   Consecutive differences
          %   STACK: F(n), F(n+1),  [0 0]
  ~       %   Logical negate, element-wise
          %   STACK: F(n), F(n+1), [1 1]
  ?       %   If top of the stack is non-empty and only contains non-zero entries
          %   (this is the case for digits '3579', but not for '3578' or '33')
          %   STACK: F(n), F(n+1)
    y     %     Duplicate from below
          %     STACK: F(n), F(n+1), F(n)
    D     %     Display immediately. This prints the copy of F(n)
          %     STACK: F(n), F(n+1)
  ]       %   End
  w       %   Swap
          %   STACK: F(n+1), F(n)
  y       %   Duplicate from below
          %   STACK: F(n+1), F(n), F(n+1)
  +       %   Add. Note that F(n)+F(n+1) is F(n+2) 
          %   STACK: F(n+1), F(n+2)
  T       %   Push true. This will be used as loop condition
          %   STACK: F(n+1), F(n+2), true
          % End (implicit). The top of the stack is consumed as loop condition.
          % Since it is true, a new iteration will begin, with the stack
          % containing F(n+1), F(n+2)

6

05AB1E , 17 16 15 bytes

тFÂ2£O¸«}ʒS¥¥_W

Pruébalo en línea!

Explicación

                  # implicitly input list of F(0) and F(1)
тF      }         # 100 times do:
  Â               # bifurcate current list
   2£             # take the first 2 items
     O            # sum
      ¸«          # append to list
         ʒ        # filter, keep only elements that are true after:
          S¥¥     # delta's of delta's of digits
             _    # logically negate each
              W   # min

5

JavaScript (ES6), 85 84 81 bytes

f=(p,q,a=[])=>p|q?f(q,p+q,![...p+''].some(x=d=n=>r=d-(d=x-(x=n)))/r?[...a,p]:a):a

Pruébalo en línea!

Prueba de dígitos adyacentes

![...p + ''].some(x = d = n => r = d - (d = x - (x = n))) / r

Tanto x como d se inicializan a una función anónima, que las fuerzas NaNde todas las operaciones aritméticas que están involucrados. La primera iteración some()da siempre (d = [function] - n) === NaNy (r = [function] - d) === NaN(Falsy). En la segunda iteración, tenemos d = x - n(un número entero) y (r = NaN - d) === NaN(falso nuevamente). A partir de la tercera iteración, r se establece en un número entero que no es cero si la diferencia entre el dígito # 3 y el dígito # 2 no es igual a la diferencia entre el dígito # 2 y el dígito # 1.

El número p cumple los criterios requeridos si y solo si some()es falso (todos los dígitos adyacentes tienen la misma diferencia) y el valor final de r es 0 (hubo al menos 3 iteraciones). Esto da !false / 0 === true / 0 === Infinity(verdad).

De lo contrario, podemos tener:

  • !true / rcon r> 0 o r <0 , lo que da false / r === 0(falso)
  • !false / NaN, que da true / NaN === NaN(falsedad)

Condición de detención

La recursión se detiene cuando se p | qevalúa a 0 . Se garantiza que esto sucederá cuando p y q alcancen valores alrededor de 10 25 que tienen una longitud de 84 bits. Como JS tiene 52 bits de mantisa, los últimos 32 bits se ponen a cero. Entonces, el OR bit a bit de 32 bits se evalúa a 0 .

Debido a la rápida tasa de crecimiento de la secuencia, esto sucede bastante rápido.


4

Java 8, 151 144 140 136 130 bytes

(a,b)->{for(long n,m,d,p;;System.out.print(m>99&p==d?m+" ":""),m=a+b,a=b,b=m)for(m=n=a,d=p=10;n>9&d==p|p>9;d=n%10-(n/=10)%10)p=d;}

Bucle infinito que genera los números cuando los encuentra.
Pruébelo en línea (agota el tiempo de espera después de 60 segundos).

Versión de 136 bytes con límite 10 10 agregado ( a<1e10):

(a,b)->{for(long n,m,d,p;a<1e10;System.out.print(m>99&p==d?m+" ":""),m=a+b,a=b,b=m)for(m=n=a,d=p=10;n>9&d==p|p>9;d=n%10-(n/=10)%10)p=d;}

Pruébalo en línea.

Explicación:

(a,b)->{         // Method with two long parameters and no return-type
  for(long n,m,  //  Temp numbers
           d,p;  //  Current and previous differences
      a<1e10;    //  Loop as long as `a` is still below 10^10
      ;          //    After every iteration:
       System.out.print(
                 //     Print:
        m>99     //      If the number has at least three digits,
        &p==d?   //      and the previous and current differences are still the same
         m+" "   //       Print the current number with a space delimiter
        :        //      Else:
         ""),    //       Print nothing
                 //     Go to the next Fibonacci iteration by:
       m=a+b,    //      Setting the temp-number `m` to `a+b`
       a=b,      //      Replacing `a` with `b`
       b=m)      //      And then setting `b` to the temp number `m`
    for(m=n=a,   //   Set both `m` and `n` to `a`
        d=p=10;  //   Set both `d` and `p` to 10
        n>9      //   Inner loop as long as `n` has at least two digits,
        &d==p    //   and `p` and `d` are still the same,
         |p>9    //   or `p` is still 10
        ;        //     After every iteration:
         d=n%10-(n/=10)%10)
                 //      Set `d` to the difference between the last two digits of `n`
                 //      And integer-divide `n` by 10 at the same time
      p=d;}      //    Set the previous difference `p` to `d`

4

Jalea , 20 19 18 bytes

>ȷ2ȧDIEƊ
+ƝḢ;Ɗȷ¡ÇƇ

Pruébalo en línea!

+ƝḢ;Ɗȷ¡produce los primeros mil ( ȷ) términos en la serie que siempre serán suficientes. Creo que probablemente hay una forma más corta de hacer esto.+ȷ¡se acerca pero solo funciona si el primer término es cero.

Supongo que podemos tomar los dos números a la inversa, lo que permite un byte DIE.

Si no estamos obligados a generar ninguna de las entradas:

Jalea , 15 bytes

>ȷ2ȧDIEƊ
+ṄÇ¡ß@

Pruébalo en línea!


55
Nuestros pensamientos a todos los bytes intrépidos que DIEƊdurante el proceso de golf.
Arnauld

4

Octava , 91 90 83 bytes

¡Guardado 7 bytes gracias a Luis Mendo!

@(t)eval"for i=3:99,if~diff(diff(+num2str(t(1))))disp(t(1))end,t=[t(2) sum(t)];end"

Pruébalo en línea!

¡Pues funciona!

evalcon for loop dentro para guardar algunos bytes. Omitir dos puntos y puntos y coma para ahorrar unos pocos. Utiliza el hecho de que un vector se considera verdadero si todos los elementos son distintos de cero para guardar anyo all.

Aparte de eso, es más o menos una implementación sencilla de Fibonacci.



2

Haskell , 105 bytes

u%v|let s=u:scanl(+)v s=[n|n<-s,d<-[f(-).map fromEnum.show$n],length d>1,and$f(==)d]
f g=zipWith g=<<tail

Define el operador (%)que devuelve una lista infinita con todas las soluciones. Para ver realmente el resultado en stdout , necesitamos deshabilitar el almacenamiento en búfer (o ejecutarlo en ghcio con runhaskell), ¡ pruébelo en línea!

Explicación / Ungolfed

La función fes solo una función auxiliar que espera una función binaria y una lista, aplica la función ga todos los pares adyacentes. Es esencialmente lo mismo que:

adjacent g xs = zipWith (tail xs) xs

El operador (%)es solo una comprensión de la lista que filtra un poco (asegurándose de que haya al menos 3 dígitos y que los dígitos adyacentes tengan la misma distancia):

u % v
  -- recursively define s as the "Fibonacci sequence" with f(0) = u and f(1) = v
  | let sequence = u : scanl (+) v sequence
  -- take all numbers from that sequence using the filters below
  = [ number | number <- sequence
  -- convert to string, get the ASCII codepoints and build a list of the adjacent differences
        , let differences = adjacent (-) . map fromEnum . show $ number
  -- numbers with > 3 digits have >= 2 adjacent digits (or rather differences of digits)
        , length differences > 1
  -- make sure all of these are equal by comparing them and reducing with logical and
        , and $ adjacent (==) differences
    ]

2

CJam , 55 bytes

q~{1$_99>"_`2\ew{{-}*}%""3,"?~_(+="0$p"*~;_@+_11_#<}g;;

Pruébalo en línea!

Mi primera presentación de CJam, no muy corta pero muy divertida. Cualquier sugerencia es bienvenida!


Eso es bueno saber, gracias por el consejo! He actualizado la presentación.
maxb

2

Stax , 26 24 bytes

Ç╕SôεPN^:·░ßⁿ {@ÿ}Ü╫╣1╣X

Ejecutar y depurarlo

Explicación

E{b+}99*L{E%2>|cd_E:-u%1=!C_Qf    # Full program, unpacked, implicit input
E                                 # Push all elements from array onto stack.
 {b+}99*L                         # Generate the first 99 numbers of the  Fibonacci sequence given the input
         {                   f    # Loop through all Fibonacci elements
          E                       # Array of decimal digit
           %2>                    # Does the array have at least 3 digits
              |c                  # Assume Truthy past this point
                d                 # discard top of stack
                 _E               # Copy the current element of the Fibonacci sequence and Digitize it
                  :-              # Pairwise difference of array.
                    :u            # Is there exactly 1 unique number
                        !C        # Flip the comparison, if truthy proceed
                          _Q      # Copy the current element of the Fibonacci sequence and Peek and print with a newline.

No es tan corto como me gustaría y probablemente pueda jugar al golf un poco más, pero funciona.



1

Julia 0.6 , 86 81 bytes

a<b=b>=0&&((n->n>99&&2>endof(∪(diff(digits(n))))&&println(n)).([a,b]);a+b<a+2b)

Pruébalo en línea!

Bastante sencillo: verifique si la entrada tiene al menos 3 dígitos ( n>99), luego tome la diferencia entre cada par de dígitos en el número ( diff(digits(n))), verifique que la longitud de ( endof) un conjunto único de ( ) esas diferencias sea 1 (es decir, todas las diferencias son los mismos), y si es así, imprima el número. Haga eso para los dos números dados, luego llame recursivamente a la función con los siguientes dos números.

(Desafortunadamente, parece que ±tiene mayor prioridad que +, o de lo contrario la llamada final podría haber sido a+b±a+2b, guardar 3 bytes.) Ahora sobrecarga al <operador, ahorrando tanto en los bytes del operador como en los corchetes de precedencia. (Sin <embargo, no se puede usar en nuestro código, así que solo se reorganizó endof(...)<2para2>endof(...) ).

Si se permite una salida extraña, podemos guardar 2 bytes usando en @showlugar de println, imprimiendo en n = 987lugar de solo 987. Incluso podríamos usar dump1 byte más bajo que eso, pero dumpimprime la información del tipo junto con el valor, por lo que la salida será en Int64 987lugar de solo 987.

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.