Trouvez les motifs de Fibonacci


16

Vous connaissez probablement la séquence de Fibonacci où les deux premiers termes sont 0, 1(ou parfois 1, 1) et chaque terme suivant est la somme des deux précédents. Cela commence comme ceci:

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

Parfois, la séquence contient des nombres qui ont un modèle particulier que je trouve intéressant: la différence entre n'importe quelle paire de chiffres adjacents est la même que n'importe quelle autre paire. Par exemple, dans la séquence commençant par 0, 1, le 18e terme est 987. 9-8=1et 8-7=1. Je suis légèrement satisfait.

Défi

Étant donné deux valeurs initiales F(0)et F(1), sortez chaque nombre dans la séquence générée par F(n) = F(n-1) + F(n-2)qui répond aux critères suivants:

  • La différence entre n'importe quelle paire de chiffres adjacents est la même que toute autre paire
  • Il comporte au moins trois chiffres (les nombres à 1 et 2 chiffres ne sont pas intéressants pour ce modèle)

Contribution

  • Deux entiers non négatifs inférieurs à 10 ** 10 (10 milliards)

Production

  • Tous les nombres entiers inférieurs à 10 ** 10 et répondant aux critères de la section Défi
  • Il est acceptable de sortir des chiffres supérieurs à 10 ** 10 mais ce n'est pas une exigence
  • Étant donné que les chiffres répétés correspondent au modèle (par exemple 777), il est possible qu'il existe des nombres infinis qui répondent aux critères, mais votre programme n'est pas obligé de produire indéfiniment
  • S'il n'existe pas de tels entiers, affichez ce que vous voulez tant qu'il ne s'agit pas d'un nombre (rien, null, tableau vide, message d'erreur, visage triste, etc.)
  • Si un nombre correspondant au modèle apparaît plusieurs fois dans la séquence, vous pouvez le sortir une ou autant de fois qu'il se produit
  • Si une entrée répond aux critères, elle doit être incluse dans la sortie

Règles

Exemples / cas de test

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
Cas de test suggéré: [1976, 123] -> [123, 2222, 4321, 6543, 45678], [3189, 826] -> [888888888],[33345, 692] -> [987654321]
Arnauld

@Arnauld Super trouvaille! Je me demande quelle paire de départ a le plus de valeurs de sortie inférieures à 10B. Tout ce qui est au-dessus sera des chiffres et c'est ennuyeux.
Ingénieur Toast

@Arnauld Merci pour les corrections du scénario de test. Dans mon générateur d'origine, je n'ai pas inclus les entrées. J'ai clairement manqué ces deux-là quand je suis retourné et les ai ajoutés.
Ingénieur Toast

Réponses:


9

MATL , 14 octets

Merci à Emigna d'avoir signalé une erreur, maintenant corrigée

`yVdd~?yD]wy+T

Boucle infinie qui sort les nombres tels qu'ils sont trouvés.

Essayez-le en ligne! Notez que dans l'interpréteur en ligne, les résultats sont affichés après le délai d'attente de 1 minute.

Explication

Soit F(n)et F(n+1)dénotons deux termes génériques consécutifs de la séquence de Fibonacci. Chaque itération de la boucle commence par la pile contenant F(n), F(n+1)pour certainsn .

`         % 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 octets

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

Essayez-le en ligne!

Explication

                  # 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 octets

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

Essayez-le en ligne!

Test des chiffres adjacents

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

Les deux x et d sont initialisés à une fonction anonyme, qui forces NaNpour toutes les opérations arithmétiques ils sont impliqués. La première itération de some()donne toujours (d = [function] - n) === NaNet (r = [function] - d) === NaN(falsy). Sur la deuxième itération, nous avons d = x - n(un entier) et (r = NaN - d) === NaN(encore une fausse). À partir de la troisième itération, r est défini sur un entier qui est différent de zéro si la différence entre le chiffre # 3 et le chiffre # 2 n'est pas égale à la différence entre le chiffre # 2 et le chiffre # 1.

Le nombre p répond aux critères requis si et seulement si some()est faux (tous les chiffres adjacents ont la même différence) et la valeur finale de r est 0 (il y a eu au moins 3 itérations). Cela donne !false / 0 === true / 0 === Infinity(véridique).

Sinon, nous pouvons avoir:

  • !true / ravec r> 0 ou r <0 , ce qui donne false / r === 0(fausse)
  • !false / NaN, ce qui donne true / NaN === NaN(fausse)

Condition d'arrêt

La récursivité s'arrête lorsqu'elle est p | qévaluée à 0 . Cela peut se produire lorsque p et q atteignent des valeurs d'environ 10 25 qui sont longues de 84 bits. Parce que JS a 52 bits de mantisse, les 32 derniers bits sont mis à zéro. Ainsi, le OU au niveau du bit 32 bits est évalué à 0 .

En raison du taux de croissance rapide de la séquence, cela se produit assez rapidement.


4

Java 8, 151 144 140 136 136 130 octets

(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;}

Boucle infinie produisant les nombres lorsqu'il les trouve.
Essayez-le en ligne (expire après 60 secondes).

Version de 136 octets avec 10 10 limites supplémentaires ( 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;}

Essayez-le en ligne.

Explication:

(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

Gelée , 20 19 18 octets

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

Essayez-le en ligne!

+ƝḢ;Ɗȷ¡produit les mille ( ȷ) premiers termes de la série qui seront toujours suffisants. Je pense qu'il existe probablement un moyen plus court de procéder. +ȷ¡se rapproche mais ne fonctionne que si le premier terme est nul.

Je suppose que nous pouvons prendre les deux nombres en sens inverse, ce qui permet à un octet de DIE.

Si nous ne sommes pas tenus de produire l'une des entrées:

Gelée , 15 octets

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

Essayez-le en ligne!


5
Nos pensées à tous les octets intrépides qui DIEƊpendant le processus de golf.
Arnauld

4

Octave , 91 90 83 octets

7 octets enregistrés grâce à Luis Mendo!

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

Essayez-le en ligne!

Et bien ça marche!

evalavec une boucle à l'intérieur pour économiser quelques octets. Ignorer les deux-points et les points-virgules pour en sauver quelques-uns. Utilise le fait qu'un vecteur est considéré comme véridique si tous les éléments ne sont pas nuls à enregistrer anyou all.

En dehors de cela, c'est à peu près une implémentation simple de Fibonacci.



2

Haskell , 105 octets

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

Définit l'opérateur (%)qui renvoie une liste infinie avec toutes les solutions. Pour voir le résultat sur stdout, nous devons désactiver la mise en mémoire tampon (ou l'exécuter dans ghciou avec runhaskell), essayez-le en ligne!

Explication / Non golfé

La fonction fest juste une fonction d'aide qui attend une fonction binaire et une liste, elle applique la fonction gà toutes les paires adjacentes. C'est essentiellement la même chose que:

adjacent g xs = zipWith (tail xs) xs

L'opérateur (%)est juste une compréhension de liste qui effectue un filtrage (en s'assurant qu'il y a au moins 3 chiffres et que les chiffres adjacents ont la même distance):

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 octets

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

Essayez-le en ligne!

Ma première soumission CJam, pas très courte mais très amusante. Toutes les suggestions sont les bienvenues!


C'est bon à savoir, merci pour l'astuce! J'ai mis à jour la soumission.
maxb

2

Stax , 26 24 octets

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

Exécuter et déboguer

Explication

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.

Pas aussi court que je le voudrais et peut probablement être joué un peu plus, mais cela fonctionne.



1

Julia 0,6 , 86 81 octets

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

Essayez-le en ligne!

Assez simple - vérifiez si l'entrée a au moins 3 chiffres ( n>99), puis prenez la différence entre chaque paire de chiffres dans le nombre ( diff(digits(n))), vérifiez que la longueur de ( endof) un ensemble unique de ( ) ces différences est 1 (c'est-à-dire toutes les différences sont les mêmes), et si oui, imprimez le numéro. Faites cela pour les deux nombres donnés, puis appelez récursivement la fonction avec les deux nombres suivants.

(Malheureusement, il semble ±avoir une priorité plus élevée que +, sinon l'appel final aurait pu être a+b±a+2b, économisant 3 octets.) Surcharge maintenant l' <opérateur, économisant ainsi à la fois les octets de l'opérateur et les crochets de priorité. (Ne peut pas utiliser <dans notre code, donc juste réorganiséendof(...)<2 en2>endof(...) ).

Si une sortie étrangère est autorisée, nous pouvons économiser 2 octets en utilisant @showau lieu de println, en imprimant n = 987au lieu de simplement 987. Nous pourrions même utiliser dumppour 1 octet inférieur à cela, mais dumpimprime les informations de type avec la valeur, donc la sortie sera Int64 987au lieu de juste 987.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.