Fibonacci benzeri dizilimdeki en düşük ilk sayılar


22

Pozitif bir tamsayı girişi N verildiğinde , iki negatif olmayan sayıyı a ve b olarak verin ; burada a <b , N sayısının yinelenen ilişki dizisinin bir parçası olmasıyla sonuçlanabilecek olası en düşük ortalama değere sahip :

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

A ve b ortalamasının en az olduğu birden fazla çözüm olması durumunda, en düşük b olanı vermelisiniz .

N'nin dilinizde / sisteminizde temsili tamsayı aralığında olduğunu varsayabilirsiniz .

Test durumları

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

Birden fazla çözüm varsa a>=0ve varsa a<b?
Jonathan Allan

Birden fazla çözüm olup olmadığını garanti edemiyorum. Hem 1,4ve 2,3verecekti 5ve onlar aynı ortalamaya sahip. Sanırım buna benzer vakalar bulmak mümkün, bunun en düşük ortalamalar olduğu yerler. Birden fazla çözüm olmadığını gösterebilir / ispatlayabilirseniz, bu durumu kontrol etmeniz gerekmez.
Stewie Griffin


3
Mümkün olan en düşük ortalama olan A249783 için karşılık gelen OEIS sekansı , vahşi görünümlü bir grafiğe sahiptir .
Peter Kagey

1
@ ØrjanJohansen Cevabımı yinelenen çözümler olmadığına dair bir kanıt ekledim (cevabım buna bağlı olduğu için).
cardboard_box

Yanıtlar:


8

Kabuğu , 19 18 16 14 13 15 bayt

1 bayt tasarruf için teşekkürler Zgarb.

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

Çevrimiçi deneyin!

Açıklama:

Yasal Uyarı:ȯƒẊ++ Kodun bölümünü gerçekten anlamıyorum .

Düzenleme: Bu Haskell çevirmek görünmektedir fix.(mapad2(+).).(++), mapad2is bir listedeki tüm komşu çiftlerine fonksiyonunu uygular. (Her ne kadar Husk'u tanımak olsa da, bu program kapsamında başka bir anlamı olabilir)

            Θḣ⁰    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)?

Ö

Bunu denedim eminim ...
H.PWiz

8

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

ThePirateBay sayesinde -3 bayt -1 bayt

-8 -9 bayt Neil sayesinde.

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]

Çevrimiçi deneyin!

Not: Bu çözüm hiçbir zaman çok sayıda minimal çözüm bulunmamasına dayanır.

Asla birden fazla çözüm olmadığının kanıtı:

Izin FIB(a,b,k)başlayarak Fibonacci benzeri dizisi olabilir 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)

Lemma 1

Fibonacci benzeri diziler arasındaki fark, kendisi Fibonacci benzeri, yani FIB(a1,b1,k) - FIB(a0,b0,k) = FIB(a1-a0,b1-b0,k). İspat okuyucuya bırakılmıştır.

Lemma 2

Çünkü tatmin edici n >= 5bir çözüm a,bvar a+b < n:

eğer öyleyse n,FIB(0,n/2,3) = n

eğer ntuhafsaFIB(1,(n-1)/2,3) = n

Kanıt

Kılıflar n < 5etraflıca kontrol edilebilir.

Biz iki asgari çözüm olduğunu varsayalım n >= 5, a0,b0ve a1,b1ile a0 + b0 = a1 + b1ve a0 != a1.

Sonra k0,k1böyle var FIB(a0,b0,k0) = FIB(a1,b1,k1) = n.

  • Dava 1: k0 = k1

    WLOG varsayalım b0 < b1(ve dolayısıyla a0 > a1)

    Izin DIFF(k)arasındaki fark Fibonnaci benzeri ile başlayan dizileri a1,b1ve a0,b0:

    DIFF(k) = FIB(a1,b1,k) - FIB(a0,b0,k) = FIB(a1-a0,b1-b0,k) (Lemma 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

    Bir Fibonnaci benzeri sekans 2 pozitif terime sahip olduğunda, sonraki tüm terimler pozitiftir.

    Böylece, tek zaman DIFF(k) = 0ne zamandır k = 2, yani tek seçenek k0 = k1budur 2.

    bu nedenle n = FIB(a0,b0,2) = a0 + b0 = a1 + b1

    Bu çözümlerin minimalliği Lemma 2 ile çelişiyor.

  • Durum 2 k0 != k1::

    WLOG varsayalım k0 < k1.

    Sahibiz FIB(a1,b1,k1) = n

    let a2 = FIB(a1,b1,k1-k0)

    let b2 = FIB(a1,b1,k1-k0+1)

    Sonra FIB(a2,b2,k0) = FIB(a1,b1,k1) = FIB(a0,b0,k0)(okuyucu için egzersiz)

    Yana FIB(a1,b1,k)negatif olmayan için k >= 0, aynı zamanda sigara azalıyor.

    Bu bize a2 >= b1 > a0ve verir b2 >= a1+b1 = a0+b0.

    Öyleyse bırak DIFF(k) = FIB(a2,b2,k) - FIB(a0,b0,k) = FIB(a2-a0,b2-b0,k)(Lemma 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

    Bir kez daha DIFF2 olumlu terim var ve bu nedenle sonraki tüm terimler olumlu.

    Böylece, bu mümkün sadece zaman DIFF(k) = 0olduğu k = 1için bu kadar tek seçenek, k0bir 1.

    FIB(a0,b0,1) = n

    b0 = n

    Bu Lemma 2 ile çelişiyor.




@Neil Bu simge simge durumuna küçültmek byerine küçültülür a+bve böylece çözümünüz f(27) = [3,7]en iyi çözümdür f(27)=[0,9]. Kırma değişikliklerini geri aldıktan sonra, 83 bayta düştük.
cardboard_box

1
Sanırım b-~ayerine başka bir bayt kaydedebilirsiniz a+b+1.
Neil

1
İkinci durumda küçük bir hata var: a2 >= a1 + b1ne zaman doğru değil k1-k0=1. Bunun yerine a2 >= b1 > a0ve kullanabilirsiniz b2 >= a1+b1 = a0+b0, sonra kalan izler.
Ørjan Johansen

8

Haskell , 76 72 74 bayt

DÜZENLE:

  • -4 bayt: @ H.PWiz , /bunun yerine divkesirli bir sayı türü kullanılmasını gerektirse de kullanılmasını önerdi .
  • +2 bayt: EnumEkleyerek aralıkları içeren bir hata düzeltildi -1.

fdeğerini Doubleveya Rationaltürünü alır ve aynı bir demet döndürür. teorik olarak sınırsız Doubleolsa da Rational, yuvarlama hatalarına neden olacak kadar büyük olmayan tüm değerler için yeterli olmalıdır .

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

Çevrimiçi deneyin! (H.PWiz'in Rationaltamsayı biçiminde giriş / çıkışlara başlık ayarlamaları ile )

Nasıl çalışır

  • ?kapsamında yerel olarak yuvalanmış bir operatördür f. a?bFibonacci benzeri sekanstan tekrar tekrar adım atarak, a,bsonuna kadar vurur, tam olarak vurursa b>=ndöndürür .Truen
  • Listede anlama:
    • sve 1arasındaki toplamı temsil eden tüm sayıları yukarıdan tekrar eder .ab
    • anumaralar arasında dolaşır 0için s/2-1. (Tek sise, aralığın sonu yukarı yuvarlanır.)
    • a?(s-a)sekansın a,s-aisabet ile başlayıp başlamadığını test eder n. Eğer öyleyse, liste kavrama tuple içerir (a,s-a). (Bu, b=s-aadlandırmaya değmeyecek kadar kısa olmasına rağmen).
    • !!0 anlamadaki ilk elemanı (vuruş) seçer.

8

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

@ Adám sayesinde 2 bayt kaydedildi

@Ngn sayesinde 12 bayt kaydedildi

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

Çevrimiçi deneyin!

Kullanır ⎕IO←0.

Nasıl? Bu gerçek delirmiş.

k←⎕ - giriş atamak k

⍳2⍴1+k←⎕- aralığının Kartezyen ürün 0için kkendisi ile

|-\¨ - sağdaki her çift elemanı soldan çıkartın ve mutlak değerler elde edin

a←,⍉ - devrik yapmak, düzleştirmek ve tayin etmek a

o←a/⍨</¨a - yalnızca sol öğenin sağdan küçük olduğu çiftleri tutun ve o

oşimdi a < baritmetik ortalamalarına göre sıralı tüm çiftlerin listesini içerir.

+\∘⌽⍣{k≤⊃⍺}¨o- içindeki her bir çift için o, kdaha yüksek bir terime ulaşılana kadar fibonacci uygulayın (çifti ve cumsum'u ters çevirin).

k∊¨- o zaman kbu son terimin olup olmadığına karar verin (yani dizide yer aldığından)

o/⍨- ve oönceki kontrolün geçerli olduğu yerde çiftleri tutmak

- ilk sonucu geri getirin.


5

Python 2 , 127 109 107 bayt

-2 OVS sayesinde bayt (değiştirme andiçin *)

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

Çevrimiçi deneyin!

Bonus puanınız var n,a,s-amı?

Açıklama:

  • İlk satır, bir Fibonacci dizisi olarak genişletilmiş golup olmadığını doğrulayan bir özyinelemeli lambda bildirir . Ayrıca , sorunun ölçütlerinden birini de kontrol eder . (Bu , ancak böyle bir durumda zaten keşfedilen ve iade edilen durumlara izin verir ). a, bxa <= ba == b0, a
    • Zincirleme eşitsizliği bir a<=b<xkerede iki kullanışlı görevi yerine getirir: doğrulama a <= bve bu b < x.
    • Eğer b < xverimleri True, fonksiyon Fibonacci sırayla sonraki iki sayı ile kendisini yeniden çağırır: b, a+b. Bu, işlevin yeni terimlerle çalışmaya devam edeceği anlamına gelir ...
    • b < xVerim olursa False, o zaman kontrol etmemiz gereken noktaya ulaştık b==x. Öyleyse, bu geri dönecek Trueve ilk çiftin a, bsonunda ulaşacağını belirtecek x. Aksi takdirde, eğer b > xçift ​​geçersiz.
  • İkinci satır, fbelirli bir değer için çözümü bulan bir başka özyinelemeli lambda bildirir n. Yinelemeli olarak yeni başlangıç ​​çiftlerini, verim a, bgelene kadar dener . Bu çözüm daha sonra iade edilir. g(n, a, b)True
    • İşlev, s(başlangıçta 1) ve a(başlangıçta 0) iki değişken kullanarak tekrar tekrar başlangıç ​​Fibonacci çiftlerini sayar . Her yinelemede, aartırılır ve a, s-ailk çift olarak kullanılır. Ancak, avurursa s, 0'a geri döndürülür ve sartırılır. Bu, çiftlerin aşağıdaki düzende sayıldığı anlamına gelir:
      s = 1 (0, 1) (1, 0)
      s = 2 (0, 2) (1, 1) (2, 0)
      s = 3 (0, 3) (1, 2), (2, 1), (3, 0)
      
      Açıkçası, bu bazı geçersiz çiftler içeriyor, ancak bunlar geçildiğinde anında elimine ediliyor g(bkz. İlk madde işareti noktası).
    • Değerler ave sböyle bulunursa g(n, a, s-a) == True, bu değer döndürülür. Olası çözümler 'boyut' sırasına göre sayıldıkça (ortalamaya, sonra min değerine göre sıralanır), bulunan ilk çözüm, meydan okuma talepleri olarak her zaman en küçük olacaktır.

3

R , 183 bayt 160 bayt

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)),]

Çevrimiçi deneyin!

23 byte golf oynadığı için teşekkürler Giuseppe

Kod açıklaması

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 bayt - genel olarak, baytları mümkün olan her yerde kaydetmelisiniz, bu nedenle hoş adlandırmaları kaldırarak 4 bayt kaydetme yalnızca kabul edilebilir veya teşvik edilmez, aynı zamanda kod-golf tarafından da istenir . Yine de güzel cevap, +1.
Giuseppe

1

Mathematica, 117 bayt

If[#==1,{0,1},#&@@SortBy[(S=Select)[S[Range[0,s=#]~Tuples~2,Less@@#&],!FreeQ[LinearRecurrence[{1,1},#,s],s]&],Mean]]&


Çevrimiçi deneyin!


1

Jöle , 19 bayt

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

Çevrimiçi deneyin!

-1 bayt sayesinde kanıtı ile cardboard_box . İspatlanmadığı takdirde UṂṚ, ikinci satırın sonuna toplamda 22 bayt ekleyebilirsiniz .


... önemli bir artış @ StewieGriffin'nin gözlemini çözmelidir.
Jonathan Allan

Ben bir his var sen bırak
Jonathan Allan

1
xEn son görünen girdiyi yapan tohumu bulmamız yeterli . Eğer x edildi çoklu üçüncü dizinde bulunmuş o zaman için çalışır 0,xve bu nedenle de ya en çalışma olacaktır 1,(x-1)/2( xtek) veya 2,x/2-1( xçift), bunun üzerine xgerçekleşmesi olmayacak kadar, sonuçta daha sonra görünür. Daha sonraki bir çarpışma için, ortalama ancak üçüncü terimler de aynıysa aynı olabilir, ancak daha sonra ilk terimler arasında daha düşük bir fark olması gerekir (aksi takdirde aynı olur) ve dolayısıyla xdaha sonraki bir dizinde bulunmuş olurlar. . Bu şekilde ṫ-Sṭµ¡i³¶ḶŒcÇÐṀdört byte tasarruf yapabiliriz .
Jonathan Allan,


@StewieGriffin Bu test davası cevap verdiğimde yoktu: p
Outgolfer Erik

1

GolfScript - 88 77 bayt

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

Carton_box sayesinde birden fazla çözümü kontrol etmedim!

açıklama

~: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

Toplu, 160 158 bayt

@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%

Bu (ayrıca) 3 7girdi verir 27. Doğru çözüm 0 9.
cardboard_box

@ cardboard_box Sorunun bunu nerede gerektirdiğini hala göremiyorum ...
Neil

İlk cümlede: "mümkün olan en düşük ortalama değer".
cardboard_box

@ cardboard_box Ah, üzgünüm, gözden kaçırmak çok kolaydı.
Neil

1
@ cardboard_box Tamam şimdi düzeltilmelidir.
Neil
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.