Temukan Pola Fibonacci


16

Anda mungkin akrab dengan urutan Fibonacci di mana dua istilah pertama adalah 0, 1(atau kadang-kadang 1, 1) dan setiap istilah setelah itu adalah jumlah dari dua sebelumnya. Dimulai seperti ini:

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

Kadang-kadang, urutan berisi angka-angka yang memiliki pola tertentu yang saya temukan menarik: perbedaan antara setiap pasangan digit yang berdekatan sama dengan pasangan lainnya. Misalnya, dalam urutan yang dimulai dengan 0, 1, istilah ke 18 adalah 987. 9-8=1dan 8-7=1. Saya agak puas.

Tantangan

Diberi dua nilai awal F(0)dan F(1), output setiap angka dalam urutan yang dihasilkan oleh F(n) = F(n-1) + F(n-2)yang memenuhi kriteria berikut:

  • Perbedaan antara setiap pasangan digit yang berdekatan adalah sama dengan pasangan lainnya
  • Paling tidak panjangnya tiga digit (angka 1 dan 2 angka tidak menarik untuk pola ini)

Memasukkan

  • Dua bilangan bulat non-negatif kurang dari 10 ** 10 (10 miliar)

Keluaran

  • Semua bilangan bulat yang kurang dari 10 ** 10 dan memenuhi kriteria di bagian Tantangan
  • Dapat diterima untuk digit keluaran lebih besar dari 10 ** 10 tetapi itu bukan keharusan
  • Mengingat bahwa angka berulang memenuhi pola (misalnya 777), ada kemungkinan bahwa ada angka tak terbatas yang memenuhi kriteria tetapi program Anda tidak diharuskan untuk menghasilkan selamanya
  • Jika tidak ada bilangan bulat seperti itu, output apa pun yang Anda inginkan asalkan bukan angka (tidak ada, null, array kosong, pesan kesalahan, wajah sedih, dll.)
  • Jika angka yang cocok dengan pola muncul lebih dari satu kali dalam urutan, Anda dapat menampilkannya sekali atau sebanyak yang terjadi
  • Jika ada input yang memenuhi kriteria, itu harus dimasukkan dalam output

Aturan

Contoh / Kasus Uji

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
Disarankan kasus uji: [1976, 123] -> [123, 2222, 4321, 6543, 45678], [3189, 826] -> [888888888],[33345, 692] -> [987654321]
Arnauld

@Arnauld Great ditemukan! Saya ingin tahu pasangan pemula mana yang memiliki nilai keluaran paling besar kurang dari 10B. Apa pun di atas itu akan menjadi repdigits dan itu membosankan.
Engineer Toast

@Arnauld Terima kasih atas koreksi kopernya. Dalam generator asli saya, saya tidak memasukkan input. Saya jelas merindukan mereka berdua ketika saya kembali dan menambahkan mereka.
Engineer Toast

Jawaban:


9

MATL , 14 byte

Terima kasih kepada Emigna karena menunjukkan kesalahan, sekarang diperbaiki

`yVdd~?yD]wy+T

Infinite loop yang menampilkan angka ketika ditemukan.

Cobalah online! Perhatikan bahwa dalam juru bahasa online hasilnya ditampilkan setelah batas waktu 1 menit.

Penjelasan

Biarkan F(n)dan F(n+1)tunjukkan dua istilah umum berturut-turut dari deret Fibonacci. Setiap iterasi dari loop dimulai dengan stack yang mengandung F(n), F(n+1)untuk beberapa 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 byte

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

Cobalah online!

Penjelasan

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

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

Cobalah online!

Menguji digit yang berdekatan

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

Baik x dan d diinisialisasi ke fungsi anonim, yang memaksa NaNuntuk semua operasi aritmatika mereka terlibat. Iterasi pertama some()selalu memberi (d = [function] - n) === NaNdan (r = [function] - d) === NaN(falsy). Pada iterasi kedua, kita memiliki d = x - n(bilangan bulat) dan (r = NaN - d) === NaN(falsy lagi). Mulai dari iterasi ketiga, r diatur ke bilangan bulat yang bukan nol jika perbedaan antara digit # 3 dan digit # 2 tidak sama dengan perbedaan antara digit # 2 dan digit # 1.

Angka p memenuhi kriteria yang diperlukan jika dan hanya jika some()falsy (semua digit yang berdekatan memiliki perbedaan yang sama) dan nilai akhir r adalah 0 (setidaknya ada 3 iterasi). Ini memberi !false / 0 === true / 0 === Infinity(kebenaran).

Kami mungkin memiliki:

  • !true / rdengan r> 0 atau r <0 , yang memberi false / r === 0(falsy)
  • !false / NaN, yang memberi true / NaN === NaN(falsy)

Kondisi terhenti

Rekursi berhenti ketika p | qdievaluasi menjadi 0 . Ini dijamin terjadi ketika p dan q mencapai nilai sekitar 10 25 yang panjangnya 84 bit. Karena JS memiliki 52 bit mantissa, 32 bit terakhir adalah nol. Jadi, bitwise 32-bit ATAU bernilai 0 .

Karena laju urutan yang tumbuh cepat, ini terjadi agak cepat.


4

Java 8, 151 144 140 136 130 byte

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

Loop tak terbatas mengeluarkan angka ketika menemukannya.
Cobalah online (waktu habis setelah 60 detik).

Versi 136 byte dengan menambahkan batas 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;}

Cobalah online.

Penjelasan:

(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

Jelly , 20 19 18 byte

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

Cobalah online!

+ƝḢ;Ɗȷ¡menghasilkan seribu ( ȷ) istilah pertama dalam seri yang akan selalu mencukupi. Saya pikir mungkin ada cara yang lebih pendek untuk melakukan ini.+ȷ¡menjadi dekat tetapi hanya berfungsi jika istilah pertama adalah nol.

Saya mengasumsikan kita dapat mengambil dua angka secara terbalik yang memungkinkan satu byte DIE .

Jika kami tidak diharuskan untuk mengeluarkan salah satu dari input:

Jelly , 15 byte

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

Cobalah online!


5
Pikiran kami untuk semua byte tanpa rasa takut yang DIEƊselama proses golf.
Arnauld



2

Haskell , 105 byte

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

Menentukan operator (%)yang mengembalikan daftar tanpa batas dengan semua solusi. Untuk benar-benar melihat hasilnya di stdout, kita perlu menonaktifkan buffering (atau menjalankannyaghci dengan atau dengan runhaskell), coba online!

Penjelasan / Tidak Diundang

Fungsi fini hanyalah fungsi pembantu yang mengharapkan fungsi biner dan daftar, itu berlaku fungsi guntuk semua pasangan yang berdekatan. Ini pada dasarnya sama dengan:

adjacent g xs = zipWith (tail xs) xs

Operator (%)hanyalah pemahaman daftar yang melakukan beberapa penyaringan (memastikan bahwa setidaknya ada 3 digit & bahwa digit yang berdekatan memiliki jarak yang sama):

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 byte

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

Cobalah online!

Pengajuan CJam pertama saya, tidak terlalu pendek tapi sangat menyenangkan. Ada saran dipersilahkan!


Itu bagus untuk diketahui, terima kasih atas tipnya! Saya telah memperbarui kiriman.
Maks

2

Stax , 26 24 byte

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

Jalankan dan debug itu

Penjelasan

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.

Tidak sesingkat yang saya inginkan dan mungkin bisa bermain golf sedikit lebih, tetapi berhasil.



1

Julia 0,6 , 86 81 byte

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

Cobalah online!

Cukup mudah - periksa apakah input memiliki setidaknya 3 digit ( n>99), lalu ambil perbedaan antara setiap pasangan digit dalam angka ( diff(digits(n))), periksa bahwa panjang ( endof) seperangkat unik ( ) perbedaan tersebut adalah 1 (yaitu semua perbedaan sama), dan jika demikian cetak nomornya. Lakukan itu untuk kedua nomor yang diberikan, kemudian panggil fungsi secara berulang dengan dua angka berikutnya.

(Sayangnya, sepertinya ±memiliki prioritas lebih tinggi daripada +, atau jika panggilan terakhir bisa a+b±a+2b, menghemat 3 byte.) Sekarang membebani <operator, sehingga menghemat pada byte operator dan kurung didahulukan. (Tidak dapat digunakan <dalam kode kami, jadi atur ulang endof(...)<2ke 2>endof(...)).

Jika beberapa output asing diperbolehkan, kita bisa menyimpan 2 bytes menggunakan @showbukannya println, mencetak n = 987bukan hanya 987. Kita bahkan bisa menggunakan dumpuntuk 1 byte lebih rendah dari itu, tetapi dumpmencetak informasi jenis bersama dengan nilainya, sehingga output akan menjadi Int64 987bukan hanya 987.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.