Các số ban đầu thấp nhất trong một chuỗi giống như Fibonacci


22

Cho đầu vào số nguyên dương N , xuất hai số không âm, ab , trong đó a <b , với giá trị trung bình thấp nhất có thể sẽ dẫn đến số N là một phần của chuỗi quan hệ định kỳ:

f(0) = a
f(1) = b
f(n) = f(n-2)+f(n-1)

Trong trường hợp có nhiều hơn một giải pháp trong đó giá trị trung bình của ab là tối thiểu, thì bạn nên xuất ra một giải pháp có b thấp nhất .

Bạn có thể giả sử N nằm trong phạm vi đại diện của số nguyên trong ngôn ngữ / hệ thống của bạn.

Các trường hợp thử nghiệm

N = 1
a = 0, b = 1

N = 15
a = 0, b = 3

N = 21
a = 0, b = 1

N = 27
a = 0, b = 9   <- Tricky test case. [3, 7] is not optimal and [4, 3] is not valid

N = 100
a = 4, b = 10

N = 101
a = 1, b = 12

N = 102
a = 0, b = 3

N = 1000
a = 2, b = 10

Nếu a>=0a<bcó bao giờ nhiều giải pháp?
Jonathan Allan

Tôi không thể đảm bảo rằng có hoặc không có nhiều giải pháp. Cả hai 1,42,3sẽ cho 5, và chúng có cùng một nghĩa. Tôi đoán có thể tìm thấy các trường hợp tương tự như trường hợp đó, trong đó đây là các giá trị trung bình thấp nhất. Nếu bạn có thể hiển thị / chứng minh rằng không có nhiều giải pháp thì bạn không cần phải kiểm tra tình trạng đó.
Stewie Griffin

2
hoàn toàn lấy cảm hứng từ codegolf.stackexchange.com/q/147200/67961
J42161217

3
Trình tự OEIS tương ứng cho giá trị trung bình thấp nhất có thể, A249783 , có một biểu đồ trông hoang dã .
Peter Kagey

1
@ RjanJohansen Tôi đã thêm một bằng chứng cho câu trả lời của mình rằng không có giải pháp trùng lặp (vì câu trả lời của tôi phụ thuộc vào nó).
cardboard_box

Câu trả lời:


8

Husk , 19 18 16 14 13 15 byte

Cảm ơn Zgarb đã tiết kiệm 1 byte.

ḟö£⁰ƒẊ++ÖΣṖ2Θḣ⁰

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

Giải trình:

Tuyên bố miễn trừ trách nhiệm: Tôi thực sự không hiểu ȯƒẊ++phần mã.

Chỉnh sửa: Nó xuất hiện để dịch sang Haskell fix.(mapad2(+).).(++), nơi mapad2áp dụng chức năng cho tất cả các cặp liền kề trong một danh sách. (Mặc dù, biết Husk, trong bối cảnh của chương trình này, nó có thể có ý nghĩa khác)

            Θḣ⁰    Create the list [0..input]
          Ṗ2       Generate all possible sublists of length 2
        ÖΣ         Sort them on their sums
ḟ                  Find the first element that satisfies the following predicate.
    ƒẊ++             Given [a,b], magically generate the infinite Fibonacci-like
                     sequence from [a,b] without [a,b] at the start.
 ö£⁰                 Is the input in that list (given that it is in sorted order)?


Tôi chắc chắn tôi đã thử điều đó ...
H.PWiz

8

JavaScript (Node.js) , 92 90 89 91 83 82 byte

-3 byte -1 byte nhờ ThePirateBay

-8 -9 byte nhờ Neil.

f=(n,a=1,b=0,c=(a,b)=>b<n?c(a+b,a):b>n)=>c(a,b)?b+2<a?f(n,a-1,b+1):f(n,b-~a):[b,a]

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

Lưu ý: giải pháp này dựa trên thực tế là không bao giờ có nhiều giải pháp tối thiểu.

Bằng chứng là không bao giờ có nhiều giải pháp:

Hãy FIB(a,b,k)là chuỗi giống như Fibonacci bắt đầu bằng a,b:

FIB(a,b,0) = a
FIB(a,b,1) = b
FIB(a,b,k) = FIB(a,b,k-1) + FIB(a,b,k-2)

Bổ đề 1

Sự khác biệt giữa các chuỗi giống như Fibonacci là chính nó giống như Fibonacci, nghĩa là FIB(a1,b1,k) - FIB(a0,b0,k) = FIB(a1-a0,b1-b0,k) . Bằng chứng là để lại cho người đọc.

Bổ đề 2

Đối với n >= 5, một giải pháp a,btồn tại thỏa mãna+b < n :

nếu nlà chẵnFIB(0,n/2,3) = n

nếu nlà số lẻ,FIB(1,(n-1)/2,3) = n

Bằng chứng

Các trường hợp n < 5có thể được kiểm tra một cách triệt để.

Giả sử chúng ta có hai giải pháp tối thiểu cho n >= 5, a0,b0a1,b1với a0 + b0 = a1 + b1a0 != a1.

Sau đó tồn tại k0,k1như vậy đó FIB(a0,b0,k0) = FIB(a1,b1,k1) = n.

  • Trường hợp 1: k0 = k1

    WLOG giả định b0 < b1(và do đó a0 > a1)

    Hãy DIFF(k)là sự khác biệt giữa các chuỗi giống như Fibonnaci bắt đầu bằng a1,b1a0,b0:

    DIFF(k) = FIB(a1,b1,k) - FIB(a0,b0,k) = FIB(a1-a0,b1-b0,k) (Bổ đề 1)

    DIFF(0) = a1 - a0 < 0

    DIFF(1) = b1 - b0 > 0

    DIFF(2) = (a1+b1) - (a0+b0) = 0

    DIFF(3) = DIFF(1) + DIFF(2) = DIFF(1) > 0

    DIFF(4) = DIFF(2) + DIFF(3) = DIFF(3) > 0

    Khi một chuỗi giống như Fibonnaci có 2 thuật ngữ tích cực, tất cả các điều khoản tiếp theo đều tích cực.

    Vì vậy, thời gian duy nhất DIFF(k) = 0là khi k = 2, vì vậy sự lựa chọn duy nhất k0 = k12.

    vì thế n = FIB(a0,b0,2) = a0 + b0 = a1 + b1

    Tính tối thiểu của các giải pháp này mâu thuẫn với Bổ đề 2.

  • Trường hợp 2 k0 != k1::

    Giả sử k0 < k1.

    Chúng ta có FIB(a1,b1,k1) = n

    Để cho a2 = FIB(a1,b1,k1-k0)

    Để cho b2 = FIB(a1,b1,k1-k0+1)

    Sau đó FIB(a2,b2,k0) = FIB(a1,b1,k1) = FIB(a0,b0,k0)(tập thể dục cho người đọc)

    FIB(a1,b1,k)không âm đối với k >= 0, nó cũng không giảm.

    Điều này cho chúng ta a2 >= b1 > a0b2 >= a1+b1 = a0+b0.

    Sau đó cho phép DIFF(k) = FIB(a2,b2,k) - FIB(a0,b0,k) = FIB(a2-a0,b2-b0,k)(Bổ đề 1)

    DIFF(0) = a2 - a0 > 0

    DIFF(1) = b2 - b0 >= (a0 + b0) - b0 = a0 >= 0

    DIFF(2) = DIFF(0) + DIFF(1) >= DIFF(0) > 0

    DIFF(3) = DIFF(1) + DIFF(2) >= DIFF(2) > 0

    Một lần nữa, DIFFcó 2 điều khoản tích cực và do đó tất cả các điều khoản tiếp theo là tích cực.

    Do đó, thời gian chỉ khi nó có thể là DIFF(k) = 0k = 1, vì vậy lựa chọn duy nhất cho k01.

    FIB(a0,b0,1) = n

    b0 = n

    Điều này mâu thuẫn với Bổ đề 2.




@Neil Điều đó giảm thiểu bthay vì giảm thiểu a+b, và do đó giải pháp của bạn đưa ra f(27) = [3,7]nhưng giải pháp tối ưu là f(27)=[0,9]. Sau khi hoàn nguyên các thay đổi vi phạm, chúng tôi xuống còn 83 byte.
cardboard_box

1
Tôi nghĩ bạn có thể lưu một byte khác bằng cách sử dụng b-~athay vì a+b+1.
Neil

1
Có một lỗi nhỏ trong trường hợp thứ hai của bạn: a2 >= a1 + b1không đúng khi nào k1-k0=1. Thay vào đó bạn có thể sử dụng a2 >= b1 > a0b2 >= a1+b1 = a0+b0, sau đó phần còn lại theo sau.
Ørjan Johansen

8

Haskell , 76 72 74 byte

CHỈNH SỬA:

  • -4 byte: @ H.PWiz đề xuất sử dụng /thay vì div, mặc dù điều này yêu cầu sử dụng loại số phân số.
  • +2 byte: Đã sửa lỗi với Enumphạm vi bằng cách thêm -1.

fnhận một giá trị Doublehoặc Rationalloại và trả về một tuple giống nhau. Doublenên đủ cho tất cả các giá trị không đủ lớn để gây ra lỗi làm tròn, trong khi Rationalvề mặt lý thuyết là không giới hạn.

f n|let a?b=b==n||b<n&&b?(a+b)=[(a,s-a)|s<-[1..],a<-[0..s/2-1],a?(s-a)]!!0

Hãy thử trực tuyến! (với các điều chỉnh tiêu đề của H.PWiz cho đầu vào / đầu raRational ở định dạng số nguyên)

Làm thế nào nó hoạt động

  • ?là một toán tử lồng nhau cục bộ trong phạm vi f. a?bcác bước đệ quy thông qua chuỗi giống như Fibonacci bắt đầu a,bcho đến khi b>=ntrả về Trueiff nchính xác.
  • Trong danh sách hiểu:
    • slặp qua tất cả các số từ 1trở lên, đại diện cho tổng ab.
    • alặp qua các số từ 0đến s/2-1. (Nếu slà số lẻ, kết thúc phạm vi làm tròn lên.)
    • a?(s-a)kiểm tra nếu chuỗi bắt đầu với a,s-alượt truy cập n. Nếu vậy, việc hiểu danh sách bao gồm bộ dữ liệu (a,s-a). (Đó là, b=s-amặc dù nó quá ngắn để có thể đặt tên.)
    • !!0 chọn phần tử đầu tiên (nhấn) trong phần hiểu.

8

APL (Dyalog) , 75 71 64 59 53 48 44 43 byte

Lưu 2 byte nhờ @ Adám

12 byte được lưu nhờ @ngn

o/⍨k∊¨+\∘⌽⍣{k≤⊃⍺}¨oa/⍨</¨a←,⍉|-21+k←⎕

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

Công dụng ⎕IO←0.

Làm sao? Điều này đã đi thực sự hạt.

k←⎕ - gán đầu vào cho k

⍳2⍴1+k←⎕- sản phẩm Descartes của dãy núi này 0đến kvới bản thân

|-\¨ - trừ từng phần tử cặp bên phải từ bên trái và nhận các giá trị tuyệt đối

a←,⍉ - hoán vị, làm phẳng và gán cho a

o←a/⍨</¨a - chỉ giữ các cặp trong đó phần tử bên trái nhỏ hơn bên phải và gán cho o

obây giờ chứa danh sách tất cả các cặp với a < b, được sắp xếp theo ý nghĩa số học của chúng

+\∘⌽⍣{k≤⊃⍺}¨o- cho mỗi cặp trong o, áp dụng Dailymotion (đảo ngược cặp và cumsum) cho đến khi kđạt được hoặc có thời hạn cao hơn

k∊¨- sau đó quyết định xem kđây có phải là thuật ngữ cuối cùng không (có nghĩa là nó được chứa trong chuỗi)

o/⍨- và giữ các cặp trong ođó áp dụng kiểm tra trước

- trả lại kết quả đầu tiên.


5

Python 2 , 127 109 107 byte

-2 byte nhờ vào ovs (thay đổi andthành *)

g=lambda x,a,b:a<=b<x and g(x,b,a+b)or b==x
f=lambda n,s=1,a=0:g(n,a,s-a)*(a,s-a)or f(n,s+(a==s),a%s+(a<s))

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

Bất kỳ điểm thưởng cho n,a,s-a?

Giải trình:

  • Dòng đầu tiên khai báo lambda đệ quy g, xác minh xem có a, bmở rộng như một chuỗi Fibonacci hay không x. Nó cũng kiểm tra rằng a <= b, một trong những tiêu chí của câu hỏi. (Điều này sẽ cho phép các trường hợp a == b, nhưng trong trường hợp như vậy 0, ađã được phát hiện và trả lại).
    • Bất đẳng thức xích a<=b<xthực hiện hai nhiệm vụ tiện dụng cùng một lúc: xác minh a <= bvà đó b < x.
    • Nếu b < xmang lại True, hàm sẽ tự gọi lại với hai số tiếp theo trong chuỗi Fibonacci : b, a+b. Điều này có nghĩa là chức năng sẽ tiếp tục thực hiện các điều khoản mới cho đến khi ...
    • Nếu b < xsản lượng False, sau đó chúng tôi đã đạt đến điểm mà chúng tôi cần kiểm tra nếu b==x. Nếu vậy, điều này sẽ trở lại True, biểu thị rằng cặp ban đầu a, bcuối cùng sẽ đạt được x. Nếu không, nếu b > x, cặp không hợp lệ.
  • Dòng thứ hai tuyên bố một lambda đệ quy khác f, tìm giải pháp cho một giá trị nhất định n. Nó đệ quy thử các cặp ban đầu mới a, b, cho đến khi đạt g(n, a, b)năng suất True. Giải pháp này sau đó được trả lại.
    • Hàm đếm đệ quy các cặp Fibonacci ban đầu bằng hai biến, s(ban đầu 1) và a(ban đầu là 0). Trên mỗi lần lặp, ađược tăng lên và a, s-ađược sử dụng làm cặp đầu tiên. Tuy nhiên, khi alần truy cập s, nó được đặt lại về 0 và sđược tăng lên. Điều này có nghĩa là các cặp được tính theo mẫu sau:
      s = 1 (0, 1) (1, 0)
      s = 2 (0, 2) (1, 1) (2, 0)
      s = 3 (0, 3) (1, 2), (2, 1), (3, 0)
      
      Rõ ràng, cái này chứa một số cặp không hợp lệ, tuy nhiên những cặp này bị loại bỏ ngay lập tức khi được chuyển đến g(xem điểm đầu tiên).
    • Khi các giá trị asđược tìm thấy như vậy g(n, a, s-a) == True, thì giá trị này được trả về. Vì các giải pháp có thể được tính theo thứ tự 'kích thước' (được sắp xếp theo giá trị trung bình, sau đó là giá trị tối thiểu), giải pháp đầu tiên được tìm thấy sẽ luôn là nhỏ nhất, như các yêu cầu thách thức.

3

R , 183 byte 160 byte

n=scan();e=expand.grid(n:0,n:0);e=e[e[,2]>e[,1],];r=e[mapply(h<-function(n,a,b,r=a+b)switch(sign(n-r)+2,F,T,h(n,b,r)),n,e[,1],e[,2]),];r[which.min(rowSums(r)),]

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

Cảm ơn Giuseppe vì đã chơi golf 23 byte

Giải thích mã

n=scan()                        #STDIO input
e=expand.grid(n:0,n:0)          #full outer join of integer vector n to 0
e=e[e[,2]>e[,1],]               #filter so b > a
r=e[mapply(
  h<-function(n,a,b,r=a+b)switch(sign(n-r)+2,F,T,h(n,b,r)),
                                #create a named recursive function mid-call 
                                #(requires using <- vs = to denote local variable creation 
                                #rather than argument assignment
  n,e[,1],e[,2]),]              #map n, a and b to h() which returns a logical
                                #which is used to filter the possibilities
r[which.min(rowSums(r)),]       #calculate sum for each possibility, 
                                #get index of the minimum and return
                                #because each possibility has 2 values, the mean and 
                                #sum will sort identically.

1
160 byte - nói chung, bạn nên lưu byte bất cứ nơi nào bạn có thể, vì vậy, tiết kiệm 4 byte bằng cách loại bỏ việc đặt tên đẹp không chỉ được chấp nhận hoặc khuyến khích mà theo một số ý nghĩa được yêu cầu bởi golf-code . Mặc dù vậy, câu trả lời hay, +1.
Giuseppe


1

Thạch , 19 byte

ṫ-Sṭµ¡³e
0rŒcÇÐfSÐṂ

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

-1 byte nhờ vào bằng chứng của tông_box . Trong trường hợp nó bị từ chối, bạn có thể nối UṂṚvào cuối dòng thứ hai với tổng số 22 byte.


... một sự gia tăng hàng đầu sẽ giải quyết sự quan sát của @ StewieGriffin.
Jonathan Allan

Tôi có cảm giác bạn có thể thả
Jonathan Allan

1
Chúng ta chỉ cần tìm hạt giống làm cho đầu vào x, xuất hiện mới nhất. Nếu x được tìm thấy ở chỉ số thứ ba cho nhiều thì nó sẽ hoạt động 0,xvà do đó cũng sẽ hoạt động ở cả 1,(x-1)/2( xlẻ) hoặc 2,x/2-1( xchẵn) xtrong đó kết quả sẽ xuất hiện sau đó trong kết quả, vì vậy điều đó sẽ không xảy ra. Đối với xung đột sau này, giá trị trung bình chỉ có thể giống nhau nếu các điều khoản thứ ba cũng giống nhau, nhưng sau đó người ta phải có sự khác biệt thấp hơn giữa các điều khoản ban đầu (nếu không chúng sẽ giống nhau) và do đó sẽ xtìm thấy ở một chỉ mục sau . Như vậy, chúng ta có thể ṫ-Sṭµ¡i³¶ḶŒcÇÐṀtiết kiệm bốn byte.
Jonathan Allan

... Rất tiếc, cộng với sự gia tăng:ṫ-Sṭµ¡i³¶‘ḶŒcÇÐṀ
Jonathan Allan

@StewieGriffin Trường hợp thử nghiệm đó đã không tồn tại khi tôi trả lời: p
Erik the Outgolfer

1

GolfScript - 88 77 byte

~:N[,{1+:a,{[.;a]}/}/][{[.~{.N<}{.@+}while\;N=]}/]{)1=\;},{(\;~+}$(\;);~~' '\

Tôi đã không kiểm tra nhiều giải pháp, nhờ có tông_box!

Giải trình

~:N                           # Reads input
[,{1+:a,{[.;a]}/}/]           # Creates an array of pairs [a b]
[{[.~{.N<}{.@+}while\;N=]}/]  # Compute solutions
{)1=\;},         # Pairs that are not solutions are discarded
{(\;~+}$         # Sorts by mean
(\;);~~' '\      # Formats output


0

Mẻ 160 158 byte

@set/aa=b=0
:g
@if %a% geq %b% set/ab-=~a,a=0
@set/ac=a,d=b
:l
@if %c% lss %1 set/ad+=c,c=d-c&goto l
@if %c% gtr %1 set/aa+=1,b-=1&goto g
@echo %a% %b%

Điều này (cũng) cung cấp cho 3 7đầu vào 27. Giải pháp đúng là 0 9.
cardboard_box

@cardboard_box Vẫn không thấy câu hỏi yêu cầu ở đâu ...
Neil

Trong câu đầu tiên: "với giá trị trung bình thấp nhất có thể".
cardboard_box

@cardboard_box À, xin lỗi, điều đó quá dễ bỏ qua.
Neil

1
@cardboard_box OK nên được sửa ngay bây giờ.
Neil
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.