Znajdź wzory Fibonacciego

16

Prawdopodobnie znasz sekwencję Fibonacciego, w której pierwsze dwa terminy są 0, 1(lub czasami 1, 1), a każdy następny po nich jest sumą dwóch poprzednich. Zaczyna się tak:

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

Czasami sekwencja zawiera liczby, które mają szczególny wzór, który uważam za interesujący: różnica między dowolną parą sąsiednich cyfr jest taka sama, jak każdej innej pary. Na przykład w sekwencji rozpoczynającej się 0, 1od 18. termin to 987. 9-8=1a 8-7=1. Jestem lekko zadowolony.

Wyzwanie

Biorąc pod uwagę dwie wartości początkowe F(0)i F(1), wypisz każdą liczbę w sekwencji wygenerowanej przez to, F(n) = F(n-1) + F(n-2)która spełnia następujące kryteria:

  • Różnica między dowolną parą sąsiednich cyfr jest taka sama, jak każdej innej pary
  • Ma co najmniej trzy cyfry (liczby 1 i 2 cyfry nie są interesujące dla tego wzoru)

Wejście

  • Dwie nieujemne liczby całkowite mniejsze niż 10 ** 10 (10 miliardów)

Wynik

  • Wszystkie liczby całkowite mniejsze niż 10 ** 10 i spełniające kryteria w części Wyzwanie
  • Dopuszczalne jest wyświetlanie cyfr większych niż 10 ** 10, ale nie jest to wymagane
  • Biorąc pod uwagę, że powtarzające się cyfry odpowiadają wzorowi (np. 777), Możliwe jest, że istnieją nieskończone liczby, które spełniają kryteria, ale Twój program nie musi wyświetlać danych zawsze
  • Jeśli nie ma takich liczb całkowitych, wypisz cokolwiek chcesz, o ile nie jest to liczba (nic, null, pusta tablica, komunikat o błędzie, smutna twarz itp.)
  • Jeśli liczba pasująca do wzorca pojawia się więcej niż jeden raz w sekwencji, możesz ją wypisać raz lub tyle razy, ile się pojawi
  • Jeżeli dane wejściowe spełniają kryteria, powinny zostać uwzględnione w danych wyjściowych

Zasady

Przykłady / przypadki testowe

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]   
Inżynier Toast
źródło
1
Sugerowane przypadki testowe: [1976, 123] -> [123, 2222, 4321, 6543, 45678], [3189, 826] -> [888888888],[33345, 692] -> [987654321]
Arnauld
@Arnauld Świetne znalezisko! Zastanawiam się, która para początkowa ma najwięcej wartości wyjściowych mniejszych niż 10B. Wszystko powyżej będzie reprodukcją i to jest nudne.
Inżynier Toast
@Arnauld Dzięki za poprawki przypadków testowych. W moim oryginalnym generatorze nie uwzględniłem danych wejściowych. Wyraźnie tęskniłem za tymi dwoma, gdy wróciłem i dodałem je.
Inżynier Toast

Odpowiedzi:

9

MATL , 14 bajtów

Dzięki Emignie za wskazanie błędu, teraz poprawionego

`yVdd~?yD]wy+T

Nieskończona pętla, która wyświetla liczby w miarę ich znajdowania.

Wypróbuj online! Pamiętaj, że w tłumaczu online wyniki są wyświetlane po upływie 1 minuty.

Wyjaśnienie

Niech F(n)i F(n+1)oznacz dwa ogólne kolejne terminy sekwencji Fibonacciego. Każda iteracja pętli zaczyna się od stosu zawierającego F(n), F(n+1)dla niektórych 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)
Luis Mendo
źródło
6

05AB1E , 17 16 15 bajtów

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

Wypróbuj online!

Wyjaśnienie

                  # 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
Emigna
źródło
5

JavaScript (ES6), 85 84 81 bajtów

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

Wypróbuj online!

Testowanie sąsiednich cyfr

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

Zarówno x oraz d są inicjowane do anonimowej funkcji, która siły NaNdla wszystkich operacji arytmetycznych są one zaangażowane w. Pierwsza iteracja some()daje zawsze (d = [function] - n) === NaNi (r = [function] - d) === NaN(falsy). Przy drugiej iteracji mamy d = x - n(liczbę całkowitą) i (r = NaN - d) === NaN(znowu fałsz). Zaczynając od trzeciej iteracji, r jest ustawiane na liczbę całkowitą, która nie jest zerowa, jeśli różnica między cyfrą # 3 i cyfrą # 2 nie jest równa różnicy między cyfrą # 2 a cyfrą # 1.

Liczba p spełnia wymagane kryteria wtedy i tylko wtedy, gdy some()występuje fałsz (wszystkie sąsiadujące cyfry mają tę samą różnicę), a końcowa wartość r wynosi 0 (były co najmniej 3 iteracje). To daje !false / 0 === true / 0 === Infinity(prawda).

W przeciwnym razie możemy mieć:

  • !true / rz r> 0 lub r <0 , co daje false / r === 0(fałsz)
  • !false / NaN, co daje true / NaN === NaN(fałsz)

Stan zatrzymania

Rekursja kończy się, gdy p | qwartość wynosi 0 . Gwarantuje to, że zarówno p, jak i q osiągną wartości około 10 25, które są 84-bitowe. Ponieważ JS ma 52 bity mantysy, ostatnie 32 bity są zerowane. Tak więc 32-bitowa bitowa operacja OR wynosi 0 .

Ze względu na szybko rosnące tempo sekwencji dzieje się to dość szybko.

Arnauld
źródło
4

Java 8, 151 144 140 136 130 bajtów

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

Nieskończona pętla wyprowadzająca liczby, gdy je znajdzie.
Wypróbuj online (upłynie limit czasu po 60 sekundach).

Wersja 136 bajtów z dodanym limitem 10 10 ( 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;}

Wypróbuj online.

Wyjaśnienie:

(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`
Kevin Cruijssen
źródło
4

Galaretka , 20 19 18 bajtów

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

Wypróbuj online!

+ƝḢ;Ɗȷ¡tworzy pierwszy tysiąc ( ȷ) terminów w serii, które zawsze będą wystarczające. Myślę, że istnieje prawdopodobnie krótszy sposób, aby to zrobić.+ȷ¡zbliża się, ale działa tylko wtedy, gdy pierwszy termin wynosi zero.

Zakładam, że możemy przyjąć dwie liczby w odwrotnej kolejności, co pozwala na jeden bajt DIE.

Jeśli nie jesteśmy zobowiązani do wyprowadzania żadnego z danych wejściowych:

Galaretka , 15 bajtów

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

Wypróbuj online!

dylnan
źródło
5
Nasze myśli do wszystkich nieustraszonych bajtów, które DIEƊpodczas gry w golfa.
Arnauld
4

Oktawa , 91 90 83 bajtów

Zaoszczędź 7 bajtów dzięki Luisowi Mendo!

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

Wypróbuj online!

Cóż, działa!

evalz pętlą for wewnątrz, aby zaoszczędzić kilka bajtów. Pomijanie dwukropków i średników, aby zaoszczędzić kilka. Wykorzystuje fakt, że wektor jest uważany za prawdziwy, jeśli wszystkie elementy są niezerowe, aby zapisać anylub all.

Poza tym jest to prawie prosta implementacja Fibonacciego.

Stewie Griffin
źródło
2

Python 2 , 102 98 bajtów

f=lambda x,y:x<1e10and[x]*(len(set(int(a)-int(b)for a,b in zip(`x`,`x`[1:])))<2<99<x)+f(y,x+y)or[]

Wypróbuj online!

Dzięki za 4 bajty z ovs

Chas Brown
źródło
2

Haskell , 105 bajtów

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

Definiuje operator, (%)który zwraca nieskończoną listę ze wszystkimi rozwiązaniami. Aby zobaczyć wynik na stdout , musimy wyłączyć buforowanie (lub uruchomić go w ghcilub z runhaskell), wypróbuj go online!

Wyjaśnienie / Niegolfowany

Funkcja fjest tylko funkcją pomocniczą, która oczekuje funkcji binarnej i listy, stosuje ją gdo wszystkich sąsiednich par. Jest zasadniczo taki sam jak:

adjacent g xs = zipWith (tail xs) xs

Operator (%)to tylko lista, która dokonuje filtrowania (upewniając się, że są co najmniej 3 cyfry i że sąsiednie cyfry mają taką samą odległość):

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
    ]
ბიმო
źródło
2

CJam , 55 bajtów

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

Wypróbuj online!

Moje pierwsze zgłoszenie do CJam, niezbyt krótkie, ale dużo zabawy. Wszelkie sugestie są mile widziane!

maxb
źródło
Dobrze wiedzieć, dziękuję za podpowiedź! Zaktualizowałem przesłanie.
maxb
2

Stax , 26 24 bajtów

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

Uruchom i debuguj

Wyjaśnienie

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.

Nie tak krótki, jak bym tego chciał i prawdopodobnie można go trochę pograć w golfa, ale działa.

Wielo
źródło
1

Julia 0.6 , 86 81 bajtów

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

Wypróbuj online!

Całkiem proste - sprawdź, czy wejście ma co najmniej 3 cyfry ( n>99), a następnie weź różnicę między każdą parą cyfr w liczbie ( diff(digits(n))), sprawdź, czy długość ( endof) ma unikalny zestaw ( ) tych różnic wynosi 1 (tzn. Wszystkie różnice są takie same), a jeśli tak, wydrukuj numer. Zrób to dla obu podanych liczb, a następnie rekurencyjnie wywołaj funkcję z następnymi dwoma liczbami.

(Niestety wygląda na to, że ±ma wyższy priorytet niż +, bo inaczej może być ostatnie wywołanie a+b±a+2b, oszczędzając 3 bajty). Teraz przeciąża <operatora, oszczędzając w ten sposób zarówno bajty operatora, jak i nawiasy priorytetowe. (Nie można jednak użyć <w naszym kodzie, więc po prostu przestawiono endof(...)<2na 2>endof(...)).

Jeśli dozwolone są jakieś zewnętrzne dane wyjściowe, możemy zaoszczędzić 2 bajty, @showzamiast printlndrukowania n = 987zamiast zamiast 987. Możemy nawet użyć dumpo 1 bajt mniej, ale dumpdrukuje informacje o typie wraz z wartością, więc wynik będzie Int64 987zamiast po prostu 987.

sundar - Przywróć Monikę
źródło