Quels sont les chiffres répétitifs de Fibonacci?

30

Comme vous le savez probablement, un nombre de Fibonacci est celui qui est la somme des deux nombres précédents de la série.

Un Fibonacci Digit ™ est celui qui est la somme des deux chiffres précédents .

Par exemple, pour le début de la série 1,1, la série serait 1,1,2,3,5,8,13,4,7,11,2...La modification se produit après le 13, où, au lieu d'ajouter 8+13, vous ajoutez 1+3. La série boucle à la fin, où 4+7=11et 1+1=2, comme au début de la série.

Pour un autre exemple, la série commençant 2,2: 2,2,4,6,10,1,1,2,3,5,8,13,4,7,11,2,3.... Celui-ci commence de manière unique, mais une fois que les chiffres sont cumulés 10, vous vous retrouvez avec 1+0=1, 0+1=1, et la série continue - et boucle - de la même manière que la 1,1série.


Le défi

Étant donné une entrée entière 0≤n≤99, calculez la boucle dans la série des chiffres de Fibonacci en commençant par ces deux chiffres. (Vous êtes certainement autorisé à considérer des nombres entiers hors de cette plage, mais ce n'est pas obligatoire.) Si une entrée à un chiffre est donnée, votre code devrait l'interpréter pour indiquer le début de la série 0,n.

Tous les nombres dans la boucle qui sont à deux chiffres doivent être sortis comme deux chiffres. Ainsi, par exemple, la boucle pour 1,1contiendrait 13, non 1,3.

La sortie commence par le premier numéro de la boucle. Ainsi, sur la base des restrictions ci-dessus, la boucle pour 1,1commence par 2, puisque 1,1et 11sont comptées séparément.

Chaque numéro de sortie peut être séparé par ce que vous voulez, tant qu'il est cohérent. Dans tous mes exemples, j'utilise des virgules, mais les espaces, les sauts de ligne, les lettres aléatoires, etc. sont tous autorisés, tant que vous utilisez toujours la même séparation. Il en 2g3g5g8g13g4g7g11va de même pour une sortie légale 1, mais ce 2j3g5i8s13m4g7sk11n'est pas le cas. Vous pouvez utiliser des chaînes, des listes, des tableaux, peu importe, à condition que vous ayez les bons nombres dans le bon ordre séparés par un séparateur cohérent. Le bracketing de la sortie entière est également autorisé (ex. (5,9,14)Ou [5,9,14], etc.).

Cas de test:

1 -> 2,3,5,8,13,4,7,11
2 -> 2,3,5,8,13,4,7,11
3 -> 11,2,3,5,8,13,4,7
4 -> 3,5,8,13,4,7,11,2
5 -> 2,3,5,8,13,4,7,11
6 -> 3,5,8,13,4,7,11,2
7 -> 14,5,9
8 -> 13,4,7,11,2,3,5,8
9 -> 11,2,3,5,8,13,4,7
0 -> 0
14 -> 5,9,14
59 -> 5,9,14

C'est le , donc le plus petit nombre d'octets gagne.

DonielF
la source
1
0n99
1
Comme dans, prenez deux entrées plutôt qu'une entrée divisée? Non
DonielF
Je ne comprends toujours pas pourquoi 14et 59donne le même résultat. Si 59est interprété comme commençant 5,9et permettant que cela fasse partie de la boucle, alors 14devrait sûrement être le début de sa boucle?
Neil
1
@williamporter Le début de la séquence est 0,1,1,2,3,5,8,13,4,7,11,2,3. La première fois que la boucle se répète est à la seconde 2.
DonielF
2
@Neil Le début de ces séquences respectives est 1,4,5,9,14,5et5,9,14,5,9 . Les deux répètent en commençant par le second 5. Comme je l'ai dit plus tôt, seule l'entrée est divisée; les numéros ultérieurs conservent leurs chiffres dans l'ordre.
DonielF

Réponses:

10

Gelée , 15 octets

DFṫ-SṭḊ
d⁵ÇÐḶZḢ

Essayez-le en ligne!

Comment ça marche

d⁵ÇÐḶZḢ  Main link. Argument: n (integer)

d⁵       Divmod 10; yield [n:10, n%10].
  ÇÐḶ    Call the helper link until a loop is reached. Return the loop.
     Z   Zip/transpose the resulting array of pairs.
      Ḣ  Head; extract the first row.


DFṫ-SṭḊ  Helper link. Argument: [a, b] (integer pair)

D        Decimal; replace a and b with the digits in base 10.
 F       Flatten the resulting array of digit arrays.
  ṫ-     Tail -1; take the last two digits.
    S    Compute their sum.
      Ḋ  Dequeue; yield [b].
     ṭ   Append the sum to [b].
Dennis
la source
6

Perl 6 , 96 78 75 octets

-3 octets grâce à nwellnhof

{0,|.comb,((*~*)%100).comb.sum...{my$a=.tail(2);m/(\s$a.*)$a/}o{@_};$_&&$0}

Essayez-le en ligne!

0 renvoie 0 et un autre nombre renvoie un objet Match qui se transforme en nombres séparés par un espace avec un espace de début en fin.

Explication:

{                                                                         }   # Anonymous code block
 0,|.comb,                    ...   # Start a sequence with 0,input
                                    # Where each element is
                          .sum      # The sum of
          (     %100).comb          # The last two digits
           (*~*)                    # Of the previous two elements joined together
                                                                         # Until
                                 {                           }o{@_}   # Pass the list into another function
                                  my$a=.tail(2); # Save the last two elements
                                                m/(\s$a.*)$a/  # The list contains these elements twice?
                                                                     # And return
                                                                   ;$_     # Input if input is 0
                                                                      &&   # Else
                                                                        $0 # The looping part, as matched
Jo King
la source
5

JavaScript (ES6),  111 104  103 octets

f=(n,o=[p=n/10|0,n%10])=>n^o[i=o.lastIndexOf(n=(q=p+[p=n])/10%10+q%10|0)-1]?f(n,[...o,n]):o.slice(i,-1)

Essayez-le en ligne!

Commenté

f = (                       // f = recursive function taking:
  n,                        //    n = last term, initialized to the input
  o = [                     //    o = sequence, initially containing:
    p = n / 10 | 0,         //      p = previous term, initialized to floor(n / 10)
    n % 10 ]                //      n mod 10
) =>                        //
  n ^                       // we compare n against
  o[                        // the element in o[] located at
    i = o.lastIndexOf(      //   the index i defined as the last position of
      n =                   //     the next term:
        (q = p + [p = n])   //       q = concatenation of p and n; update p to n
        / 10 % 10           //       compute the sum of the last two digits
        + q % 10            //       of the resulting string
        | 0                 //       and coerce it back to an integer
      ) - 1                 //   minus 1
  ] ?                       // if o[i] is not equal to n:
    f(n, [...o, n])         //   append n to o[] and do a recursive call
  :                         // else:
    o.slice(i, -1)          //   we've found the cycle: return it
Arnauld
la source
5

Python 3 , 187 176 158 139 138 129 121 120 112 96 95 120 116 octets

f=lambda n,m=0,z=[]:(n,m)in zip(z,z[1:])and z[z.index(m)::-1]or f((z and n//10or m%10)+n%10,z and n or n//10,(m,*z))

Essayez-le en ligne!

Edit: Comme indiqué par @ Jules , une solution plus courte s'applique à Python 3.6+. Plus de solutions distinctes pour Python 3 / 3.6+

Edit: l'indexation de zétait trop verbeuse. Sans cela maintenant, il n'y a aucun gain à utiliser eval.

Edit: recherche simplifiée si les deux derniers éléments sont déjà apparus dans la séquence.

Modifier: format de sortie modifié de la liste en tuple + remplacé lambdapardef

Edit: Retour à lambdamais intégré tdans f.

Edit: l'entrée npeut en fait être interprétée comme le chef d'une collection croissante zqui représenterait la queue dans une approche récursive. Bat également à nouveau la solution de @ Arbo .

Edit: En fait, vous pouvez déballer deux éléments de la tête, ce qui coupe encore 16 octets.

Edit: en fait 17 octets.

Edit: Comme indiqué par @ Arbo, la solution donnait des réponses 14et des 59cas comme dans les cas de test initiaux qui se sont avérés plus tard erronés. Pour l'instant ce n'est pas si court mais au moins ça marche correctement.


Tout un abus de f-stringset eval. Code original non golfé bien que je soupçonne que cela pourrait être fait d'une manière plus simple:

def is_subsequence(l1, l2):
    N, n = len(l1), len(l2)
    for i in range(N-n):
        if l1[i:i+n]==l2:
            return True
    return False

def generate_sequence(r):
    if is_subsequence(r,r[-2:]):
        return r
    last_two_digits = "".join(map(str,r))[-2:]
    new_item = sum(int(digit) for digit in last_two_digits)
    return generate_sequence(r + [new_item])

def f(n):
    seq = generate_sequence([n,n])[::-1]
    second_to_last = seq[1]
    first_occurence = seq.index(second_to_last)
    second_occurence = seq.index(second_to_last, first_occurence + 1)
    return seq[first_occurence + 1 : second_occurence + 1][::-1]
Nishioka
la source
1
Petite correction: c'est Python 3.6+. Cela ne fonctionnera manifestement pas dans la version 3.5 ou antérieure.
0xdd
1
Votre code de test semble ne pas fonctionner; une entrée de 59rendements(14, 5, 9)
ArBo
Je vois que les cas de test ont changé depuis que j'ai commencé le défi, c'est pourquoi il y a eu une sortie incorrecte. J'ai changé ma solution pour qu'elle fonctionne mais pour l'instant ce n'est pas si court. Merci néanmoins de l'avoir signalé.
Nishioka
4

C (gcc) , 114 112 109 octets

f(n,s){int i[19]={};for(s=n/10,n%=10;i[s]-n;n+=n>9?-9:s%10,s=i[s])i[s]=n;for(;printf("%d ",s),i[s=i[s]]-n;);}

Essayez-le en ligne!

-3 depuis le plafond

Comprend un espace de fuite.

f(n,s){
    int i[19]={};                               //re-initialize edges for each call
    for(s=n/10,n%=10;                           //initialize from input
        i[s]-n;                                 //detect loop when an edge s->n repeats
        n+=n>9?-9:s%10,s=i[s])i[s]=n;           //step
    for(;printf("%d ",s),i[s=i[s]]-n;);         //output loop
}
attinat
la source
1
hein, do...whilen'a pas besoin des accolades s'il s'agit d'une seule déclaration O_o
ASCII uniquement
3

Perl 5, 90 76 octets

s/.\K/ /;s/(.?) *(.)\K$/$".($1+$2)/e until/^0|\b(.\B.|. .)\b.*(?= \1)/;$_=$&

TIO

Nahuel Fouilleul
la source
@JoKing, fixe et optimisé
Nahuel Fouilleul
2

Java (JDK) , 194 octets

n->"acdfinehlcdfinehfjofj".chars().map(x->x-97).skip((n="abbicbcsfibbbgqifiibbgbbbcsfbiiqcigcibiccisbcqbgcfbffifbicdqcibcbicfsisiibicfsiffbbicfsifiibicfsifii".charAt(n)%97)).limit(n<1?1:n<9?8:3)

Essayez-le en ligne!

Le code dur semblait le plus court étant donné que Python avait déjà une réponse de 187 ...

Olivier Grégoire
la source
2

Haskell, 100 octets

d!p@(s,t)|(_,i:h)<-span(/=p)d=fst<$>i:h|q<-d++[p]=q!(t,last$mod s 10+t:[t-9|t>9])
h x=[]!divMod x 10

Essayez-le en ligne!

d!p@(s,t)                -- function '!' recursively calculates the sequence
                         -- input parameter:
                         -- 'p': pair (s,t) of the last two numbers of the sequence
                         -- 'd': a list of all such pairs 'p' seen before
  |       <-span(/=p)d   -- split list 'd' into two lists, just before the first
                         -- element that is equal to 'p'
   (_,i:h)               -- if the 2nd part is not empty, i.e. 'p' has been seen
                         -- before
          =fst<$>i:h     -- return all first elements of that 2nd part. This is
                         -- the result.
  |q<-d++[p]             -- else (p has not been seen) bind 'q' to 'd' followed by 'p'
   =q!                   -- and make a recursive call to '!' with 'q' and
     (t,    )            -- make the last element 't' the second to last element
                         -- the new last element is
          [t-9|t>9]      -- 't'-9 (digit sum of 't'), if 't'>9
       mod s 10+t        -- last digit of 's' plus 't', otherwise

h x=                     -- main function
     []!divMod x 10      -- call '!' with and empty list for 'd' and
                         -- (x/10,x%10) as the pair of last numbers
nimi
la source
2

Python 2 , 123 114 113 113 octets

n=input()
p=b=l=n/10,n%10
while~-(b in p):p+=b,;l+=(b[1]/10or b[0]%10)+b[1]%10,;b=l[-2:]
print l[p.index(b)-2:-2]

Essayez-le en ligne!

Le programme crée un tuple pde toutes les paires de 2 valeurs qui se sont produites dans la séquence, qui est initialisé avec du courrier indésirable pour enregistrer certains octets. La séquence elle-même est intégrée dans le tuple l, et les deux derniers éléments de ce tuple sont stockés bpour une référence facile (et courte). Dès qu'une répétition est trouvée, nous pouvons rechercher l'indice de binp savoir où la boucle a commencé.

EDIT: Nettoyé un peu et rasé un octet de plus ... Ma méthode semble approcher de sa limite de nombre d'octets, et je devrais vraiment arrêter de travailler dessus.

ArBo
la source
1

charbon , 46 octets

≔E◧S²ΣιθW¬υ≔ΦE⊖L⊞OθΣ…⮌⪫θω²✂θλLθ¹⁼κ✂θ⊗⁻λLθλ¹υIυ

Essayez-le en ligne!Le lien est vers la version détaillée du code. Explication:

≔E◧S²Σιθ

Saisissez le nombre, complétez-le à 2 caractères, puis prenez la somme numérique de chaque caractère et enregistrez la liste résultante.

W¬υ

Répétez pendant que la liste des boucles est vide.

⊞OθΣ…⮌⪫θω²

Calculez la somme des deux chiffres précédents et ajoutez-la à la liste de Fibonacci.

E⊖L...✂θλLθ¹

Prenez tous les suffixes non triviaux de la liste.

≔Φ...⁼κ✂θ⊗⁻λLθλ¹υ

Filtrez celles qui ne se répètent pas et enregistrez le résultat dans la liste des boucles.

Iυ

Castez la liste des boucles en chaîne et imprimez.

Neil
la source
1

Rouge , 189 178 164 137 137 octets

func[n][b: n % 10 c: reduce[a: n / 10]until[append c e: b
b: a *(pick[0 1]b > 9)+(a: b % 10)+(b / 10)k: find c reduce[e b]]take/last k k]

Essayez-le en ligne!

Galen Ivanov
la source
1

Python 2 , 149 139 octets

s=input()
s=[s/10,s%10]
while zip(s,s[1:]).count((s[-2],s[-1]))<2:s+=[(s[-1]/10or s[-2]%10)+s[-1]%10]
print s[-s[::-1].index(s[-2],2)-1:-2]

Essayez-le en ligne!

Attend un entier non négatif en entrée. Bytecount plus petit, mais ne fonctionnera probablement plus pour les entiers> 99.

Explication:

# get the input from STDIN
s=input()
# convert the input into two integers via a divmod operation
s=[s/10,s%10]
# count number of times the last two numbers appear in sequence in list.
# turn list into list of adjacent value pairs Ex: [1,1,2]->[(1,1),(1,2)]
      zip(s,s[1:])
                  # count number of times the last two items in list appear in entire list
                  .count((s[-2],s[-1]))
# if >1 matches, we have found a repeat.
while .................................<2:
        # the first digit of the last number, if it is >9
        # else the last digit of the second to last number
        (s[-1]/10or s[-2]%10)
                             # the last digit of the last number
                             +s[-1]%10
    # add the new item to the list
    s+=[..............................]
         # reverse the list, then find the second occurrence of the second to last item
         s[::-1].index(s[-2],2)
# get the section of the list from the second occurrence from the end, discard the final two items of the list
print s[-......................-1:-2]
Triggernométrie
la source