Tìm các mẫu Fibonacci


16

Có lẽ bạn đã quen thuộc với chuỗi Fibonacci trong đó hai thuật ngữ đầu tiên là 0, 1(hoặc đôi khi 1, 1) và mọi thuật ngữ sau đó là tổng của hai thuật ngữ trước. Nó bắt đầu như thế này:

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

Đôi khi, chuỗi chứa các số có một mẫu cụ thể mà tôi thấy thú vị: sự khác biệt giữa bất kỳ cặp chữ số liền kề nào cũng giống như bất kỳ cặp nào khác. Chẳng hạn, trong chuỗi bắt đầu bằng 0, 1, số hạng thứ 18 là 987. 9-8=18-7=1. Tôi hài lòng nhẹ.

Thử thách

Đưa ra hai giá trị ban đầu F(0)F(1), xuất ra mọi số trong chuỗi được tạo bởi F(n) = F(n-1) + F(n-2)đáp ứng các tiêu chí sau:

  • Sự khác biệt giữa bất kỳ cặp chữ số liền kề nào cũng giống như bất kỳ cặp nào khác
  • Nó dài tối thiểu ba chữ số (số 1 và 2 chữ số không thú vị đối với mẫu này)

Đầu vào

  • Hai số nguyên không âm dưới 10 ** 10 (10 tỷ)

Đầu ra

  • Tất cả các số nguyên nhỏ hơn 10 ** 10 và đáp ứng các tiêu chí trong phần Thử thách
  • Có thể chấp nhận các chữ số đầu ra lớn hơn 10 ** 10 nhưng nó không phải là một yêu cầu
  • Cho rằng các chữ số lặp lại đáp ứng mẫu (ví dụ 777), có thể có các số vô hạn đáp ứng các tiêu chí nhưng chương trình của bạn không bắt buộc phải xuất ra mãi mãi
  • Nếu không có số nguyên nào như vậy tồn tại, hãy xuất bất cứ thứ gì bạn muốn miễn là nó không phải là số (không có gì, null, mảng trống, thông báo lỗi, mặt buồn, v.v.)
  • Nếu một số khớp với mẫu xuất hiện nhiều lần trong chuỗi, bạn có thể xuất nó một lần hoặc nhiều lần khi nó xảy ra
  • Nếu bất kỳ đầu vào nào đáp ứng các tiêu chí, thì nó nên được đưa vào đầu ra

Quy tắc

Ví dụ / Trường hợp kiểm tra

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
Trường hợp kiểm tra đề nghị: [1976, 123] -> [123, 2222, 4321, 6543, 45678], [3189, 826] -> [888888888],[33345, 692] -> [987654321]
Arnauld

@Arnauld Tuyệt vời tìm thấy! Tôi tự hỏi cặp bắt đầu nào có giá trị đầu ra nhỏ nhất dưới 10B. Bất cứ điều gì ở trên đó sẽ là kỹ thuật số và đó là nhàm chán.
Kỹ sư Toast

@Arnauld Cảm ơn bạn đã sửa chữa trường hợp thử nghiệm. Trong trình tạo ban đầu của tôi, tôi không bao gồm các đầu vào. Tôi rõ ràng đã bỏ lỡ hai người đó khi tôi quay lại và thêm chúng.
Kỹ sư Toast

Câu trả lời:


9

MATL , 14 byte

Cảm ơn Emigna đã chỉ ra một lỗi, giờ đã sửa

`yVdd~?yD]wy+T

Vòng lặp vô hạn mà đầu ra các số khi chúng được tìm thấy.

Hãy thử trực tuyến! Lưu ý rằng trong trình thông dịch trực tuyến, kết quả được hiển thị sau khi hết thời gian 1 phút.

Giải trình

Cho F(n)F(n+1)biểu thị hai thuật ngữ chung liên tiếp của chuỗi Fibonacci. Mỗi lần lặp của vòng lặp bắt đầu với ngăn xếp chứa F(n), F(n+1)đối với một số 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

Hãy thử trực tuyến!

Giải trình

                  # 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

Hãy thử trực tuyến!

Kiểm tra các chữ số liền kề

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

Cả xd đều được khởi tạo thành một hàm ẩn danh, điều này buộc NaNtất cả các phép toán số học mà chúng tham gia. Lần lặp đầu tiên some()luôn luôn cho (d = [function] - n) === NaN(r = [function] - d) === NaN(giả). Ở lần lặp thứ hai, chúng ta có d = x - n(một số nguyên) và (r = NaN - d) === NaN(lại sai). Bắt đầu từ lần lặp thứ ba, r được đặt thành một số nguyên khác không nếu chênh lệch giữa chữ số 3 và chữ số 2 không bằng chênh lệch giữa chữ số 2 và chữ số 1.

Số p đang đáp ứng các tiêu chí bắt buộc khi và chỉ khi some()là sai (tất cả các chữ số liền kề có cùng mức chênh lệch) và giá trị cuối cùng của r0 (có ít nhất 3 lần lặp). Điều này cho !false / 0 === true / 0 === Infinity(sự thật).

Chúng tôi có thể có:

  • !true / rvới r> 0 hoặc r <0 , sẽ cho false / r === 0(giả)
  • !false / NaN, mà cho true / NaN === NaN(giả)

Tình trạng tạm dừng

Đệ quy dừng khi p | qước lượng bằng 0 . Điều này được đảm bảo xảy ra khi cả pq đạt giá trị khoảng 10 25 dài 84 bit. Vì JS có 52 bit mantissa, 32 bit cuối cùng bằng 0. Vì vậy, bit-bit 32 bit HOẶC ước tính thành 0 .

Do tốc độ tăng trưởng nhanh của chuỗi, điều này xảy ra khá nhanh.


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

Vòng lặp vô hạn xuất ra các số khi nó tìm thấy chúng.
Dùng thử trực tuyến (thời gian chờ sau 60 giây).

Phiên bản 136 byte có thêm 10 10 giới hạn ( 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;}

Hãy thử trực tuyến.

Giải trình:

(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

Thạch , 20 19 18 byte

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

Hãy thử trực tuyến!

+ƝḢ;Ɗȷ¡tạo ra hàng ngàn ( ȷ) thuật ngữ đầu tiên trong chuỗi sẽ luôn luôn đủ. Tôi nghĩ rằng có lẽ có một cách ngắn hơn để làm điều này. +ȷ¡được gần nhưng chỉ hoạt động nếu thuật ngữ đầu tiên bằng không.

Tôi giả sử chúng ta có thể lấy hai số ngược lại cho phép một byte đến DIE.

Nếu chúng tôi không bắt buộc phải xuất một trong hai đầu vào:

Thạch , 15 byte

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

Hãy thử trực tuyến!


5
Suy nghĩ của chúng tôi về tất cả các byte không sợ hãi DIEƊtrong quá trình chơi gôn.
Arnauld

4

Octave , 91 90 83 byte

Đã lưu 7 byte nhờ Luis Mendo!

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

Hãy thử trực tuyến!

Vâng, nó hoạt động!

evalvới vòng lặp for bên trong để lưu một vài byte. Bỏ qua dấu hai chấm và dấu chấm phẩy để tiết kiệm một ít. Sử dụng thực tế là một vectơ được coi là trung thực nếu tất cả các phần tử đều khác không để lưu anyhoặc all.

Ngoài ra, đó là cách triển khai thẳng tiến của Fibonacci.



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

Xác định toán tử (%)trả về một danh sách vô hạn với tất cả các giải pháp. Để thực sự thấy kết quả trên thiết bị xuất chuẩn, chúng ta cần phải tắt bộ đệm (hoặc chạy nó trong ghcihoặc với runhaskell), hãy thử trực tuyến!

Giải thích / Ungolfed

Hàm fnày chỉ là một hàm trợ giúp mong đợi một hàm nhị phân và một danh sách, nó áp dụng hàm này gcho tất cả các cặp liền kề. Về cơ bản nó giống như:

adjacent g xs = zipWith (tail xs) xs

Toán tử (%)chỉ là một sự hiểu biết danh sách thực hiện một số bộ lọc (đảm bảo rằng có ít nhất 3 chữ số & các chữ số liền kề có cùng khoảng cách):

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

Hãy thử trực tuyến!

Bài nộp đầu tiên của tôi về CJam, không quá ngắn nhưng rất nhiều niềm vui. Mọi góp ý đều được chào đón!


Đó là điều tốt để biết, cảm ơn vì tiền boa! Tôi đã cập nhật trình.
maxb

2

Stax , 26 24 byte

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

Chạy và gỡ lỗi nó

Giải trình

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.

Không ngắn như tôi muốn và có thể chơi gôn nhiều hơn một chút, nhưng nó hoạt động.



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)

Hãy thử trực tuyến!

Khá đơn giản - kiểm tra xem đầu vào có ít nhất 3 chữ số ( n>99) hay không, sau đó lấy chênh lệch giữa mỗi cặp chữ số trong số ( diff(digits(n))), kiểm tra xem độ dài của ( endof) một tập hợp duy nhất của ( ) những khác biệt đó là 1 (tức là tất cả các khác biệt là như nhau), và nếu vậy in số. Làm điều đó cho cả hai số đã cho, sau đó gọi đệ quy hàm với hai số tiếp theo.

(Thật không may, có vẻ như ±có mức độ ưu tiên cao hơn +, hoặc nếu không thì cuộc gọi cuối cùng có thể là a+b±a+2b, tiết kiệm 3 byte.) Bây giờ làm quá tải <toán tử, do đó tiết kiệm cả byte toán tử và dấu ngoặc ưu tiên. (Không thể sử dụng <trong mã của chúng tôi mặc dù, vì vậy chỉ cần sắp xếp lại endof(...)<2để 2>endof(...)).

Nếu một số lượng không liên quan nào được phép, chúng ta có thể tiết kiệm 2 byte sử dụng @showthay vì println, in n = 987thay vì chỉ 987. Chúng tôi thậm chí có thể sử dụng dumpcho 1 byte thấp hơn mức đó, nhưng dumpin thông tin loại cùng với giá trị, vì vậy đầu ra sẽ Int64 987thay vì chỉ 987.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.