フィボナッチのようなシーケンスの最小の初期数


22

正の整数入力Nが与えられると、2つの非負の数abを出力します。ここでa <bであり、数Nが繰り返し関係シーケンスの一部となる可能な最小の平均値を持ちます。

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

場合には、平均以上の解決策があるとbが、その後、最小限であるあなたが出力すべき最低で1 B

Nは、言語/システムの整数の代表的な範囲内にあると仮定できます。

テストケース

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

複数のソリューションがある場合a>=0、それa<bはありますか?
ジョナサンアラン

複数のソリューションがあるかどうかを保証することはできません。どちら1,42,3与えるだろう5、と彼らは同じ平均値を持ちます。私は、それらが最も低い平均値であるケースに類似したケースを見つけることが可能であると思います。複数の解決策がないことを証明/証明できる場合は、その状態を確認する必要はありません。
スティーヴィーグリフィン


3
可能な最小平均A249783に対応するOEISシーケンスには、ワイルドなグラフがあります
ピーターカゲィ

1
@ØrjanJohansen回答に重複した解決策がないことの証明を追加しました(回答がそれに依存しているため)。
cardboard_box

回答:


8

ハスク19 18 16 14 13 15バイト

1バイトを保存してくれたZgarbに感謝します。

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

オンラインでお試しください!

説明:

免責事項:私は本当にȯƒẊ++コードのセクションを理解していません。

編集:Haskellのに変換するように見えるfix.(mapad2(+).).(++)mapad2ISは、リスト内のすべての隣接する対に関数を適用します。(ただし、Huskを知っていても、このプログラムのコンテキストでは、何か他のものを意味する可能性があります)

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


私はそれを試みたと確信しています...
H.PWiz

8

JavaScript(Node.js)92 90 89 91 83 82バイト

-3バイト -1バイトThePirateBayのおかげ

-8 -9ニールのおかげでバイト。

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]

オンラインでお試しください!

注:このソリューションは、複数の最小ソリューションが存在しないという事実に依存しています。

複数のソリューションが存在しないことの証明:

ましょうFIB(a,b,k)フィボナッチのようなシーケンスで始まる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)

補題1

フィボナッチに似たシーケンスの違いは、それ自体がフィボナッチに似ていFIB(a1,b1,k) - FIB(a0,b0,k) = FIB(a1-a0,b1-b0,k)ます。証拠は読者に任されています。

補題2

についてn >= 5は、以下a,bを満たす解が存在しますa+b < n

場合nでもあり、FIB(0,n/2,3) = n

nが奇数の場合、FIB(1,(n-1)/2,3) = n

証明

n < 5徹底的に確認できるケース。

我々は2つの最小限のソリューションを持っていると仮定しn >= 5a0,b0a1,b1してa0 + b0 = a1 + b1a0 != a1

そして、k0,k1そのようなものが存在しFIB(a0,b0,k0) = FIB(a1,b1,k1) = nます。

  • 事例1: k0 = k1

    WLOGは想定しているb0 < b1(したがってa0 > a1

    ましょうDIFF(k)とで始まるフィボナッチのようなシーケンスの違いにa1,b1なりa0,b0ます:

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

    Fibonnaciのようなシーケンスに2つの正の用語が含まれると、後続のすべての用語は正になります。

    したがって、唯一の時間DIFF(k) = 0はwhen k = 2であるため、の唯一の選択肢はk0 = k1です2

    だから n = FIB(a0,b0,2) = a0 + b0 = a1 + b1

    これらのソリューションの最小限度は、補題2と矛盾しています。

  • ケース2 k0 != k1::

    WLOGは仮定しk0 < k1ます。

    我々は持っています FIB(a1,b1,k1) = n

    させて a2 = FIB(a1,b1,k1-k0)

    させて b2 = FIB(a1,b1,k1-k0+1)

    次にFIB(a2,b2,k0) = FIB(a1,b1,k1) = FIB(a0,b0,k0)(読者のための運動)

    FIB(a1,b1,k)は負ではないのでk >= 0、減少していません。

    これは、私たちを与えるa2 >= b1 > a0b2 >= a1+b1 = a0+b0

    それではDIFF(k) = FIB(a2,b2,k) - FIB(a0,b0,k) = FIB(a2-a0,b2-b0,k)(補題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

    繰り返しますが、DIFF2つの正の用語があるため、後続の用語はすべて正です。

    したがって、それが可能な唯一の時間DIFF(k) = 0k = 1ですので、の唯一の選択肢はk0です1

    FIB(a0,b0,1) = n

    b0 = n

    これは補題2と矛盾しています。




@Neilこれは最小化するb代わりに最小化するため、最適なソリューションはa+bとなります。重大な変更を元に戻した後、83バイトになりました。f(27) = [3,7]f(27)=[0,9]
cardboard_box

1
b-~a代わりにを使用して別のバイトを保存できると思いますa+b+1
ニール

1
2番目のケースでは、小さなエラーがあります:a2 >= a1 + b1とき修正されていませんk1-k0=1。代わりにa2 >= b1 > a0and を使用できb2 >= a1+b1 = a0+b0、残りは続きます。
Ørjanヨハンセン

8

Haskell76 72 74バイト

編集:

  • -4バイト:@ H.PWiz /div、これには小数型を使用する必要があります。
  • +2バイト:Enumを追加して範囲のバグを修正しました-1

fDoubleまたはRationalタイプを取り、同じタプルを返します。 理論上は無制限ですがDouble、丸めエラーを引き起こすほど大きくないすべての値で十分ですRational

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.PWizの入力/出力に対するヘッダー調整によりRational整数形式の)

使い方

  • ?は、のスコープ内でローカルにネストされた演算子ですf。until でa?b始まるフィボナッチのようなシーケンスを再帰的にステップ実行し、正確にヒットした場合にのみ返します。a,bb>=nTruen
  • リスト内包表記:
    • s1の合計を表す上からすべての数値を反復処理します。ab
    • aから0までの数字を反復処理しs/2-1ます。(s奇数の場合、範囲の終わりは切り上げられます。)
    • a?(s-a)a,s-ahitsで始まるシーケンスがテストされnます。その場合、リストの内包にはtupleが含まれ(a,s-a)ます。(つまり、b=s-a名前を付けるには短すぎましたが。)
    • !!0 内包表記の最初の要素(ヒット)を選択します。

8

APL(Dyalog)75 71 64 59 53 48 44 43バイト

@Adámのおかげで2バイト節約

@ngnのおかげで12バイト節約

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

オンラインでお試しください!

を使用し⎕IO←0ます。

どうやって? これは本当のことです。

k←⎕ -入力を割り当てる k

⍳2⍴1+k←⎕-範囲のデカルト積0k自体と

|-\¨ -左から各右のペア要素を減算し、絶対値を取得します

a←,⍉ -転置、平坦化、および割り当て a

o←a/⍨</¨a -左の要素が右よりも小さいペアのみを保持し、に割り当てます o

o 現在、すべてのペアのリストが含まれています a < bれ、算術平均順に並べられています

+\∘⌽⍣{k≤⊃⍺}¨o-の各ペアに対してo、フィボナッチ(ペアとカムサムを逆に)を適用しますkまたはそれ以上の用語に達しました

k∊¨ -その後、決定する kこの最後の用語である(つまり、シーケンスに含まれていることを意味します)

o/⍨ -ペアを保持する o、前のチェックが適用される場所でます

-最初の結果を返します。


5

パイソン2127 109 107バイト

-2 OVSのおかげでバイト(変化andします*

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

オンラインでお試しください!

のボーナスポイントはn,a,s-a

説明:

  • 最初の行は、再帰ラムダを宣言します。gこれはa, b、フィボナッチ数列がに達すると展開されるかどうかを検証しxます。またa <= b、質問の基準の1つもチェックします。(これにより、の場合が許可されますa == bが、そのような場合、0, aすでに発見されて返送されているはずです)。
    • 連鎖不等式a<=b<xa <= b、検証、およびb < xます。
    • 場合はb < x利回りTrue、機能はフィボナッチ数列の次の二つの数字で再び自身を呼び出します。b, a+b。これは、関数が...まで新しい用語を作り続けることを意味します
    • 場合はb < x利回りFalse、我々は我々がいるかどうかを確認する必要がある点に達していますb==x。その場合、これはを返しTrue、最初のペアa, bが最終的にに到達することを意味しますx。そうでない場合、の場合b > x、ペアは無効です。
  • 2行目はf、別の再帰ラムダを宣言しますn。これは、指定されたvalueの解を見つけます。yields a, bになるまで、新しい初期ペアを再帰的に試行しg(n, a, b)ますTrue。その後、このソリューションが返されます。
    • この関数は、2つの変数s(最初は1)とa(最初は0)を使用して、初期フィボナッチペアを再帰的にカウントします。反復ごとに、a増分a, s-aされ、最初のペアとして使用されます。ただし、をa押すsと0にリセットされ、s増分されます。これは、ペアが次のパターンでカウントアップされることを意味します。
      s = 1(0、1)(1、0)
      s = 2(0、2)(1、1)(2、0)
      s = 3(0、3)(1、2)、(2、1)、(3、0)
      
      明らかに、これにはいくつかの無効なペアが含まれていますが、これらは渡されるとすぐに削除されますg(最初の箇条書きを参照)。
    • ときの値asなるように発見されg(n, a, s-a) == True、この値が返されます。可能なソリューションは「サイズ」の順にカウントアップされるため(平均値、最小値の順)、最初に見つかったソリューションは、チャレンジリクエストとして常に最小になります。

3

R183バイト 160バイト

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

オンラインでお試しください!

23バイトのゴルフをしてくれたGiuseppeに感謝

コードの説明

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バイト -一般に、できる限りバイトを保存する必要があります。したがって、素敵な名前を削除して4バイトを保存することは、受け入れられるか推奨されるだけでなく、ある意味でcode-golfに必要です。それでも、いい答え、+ 1。
ジュゼッペ


1

ゼリー、19バイト

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

オンラインでお試しください!

-1バイトのおかげ証拠によってcardboard_box。反証がある場合UṂṚは、2行目の最後に合計22バイトを追加できます。


...先行する増分が@StewieGriffinの観測を解決するはずです。
ジョナサンアラン

私が感じているあなたがドロップすることができます
ジョナサン・アラン

1
入力をx最新にするシードを見つけるだけです。場合x された複数のための第三のインデックスで発見、それがために働く0,xので、またいずれかでの作業でしょう1,(x-1)/2x奇数)または2,x/2-1xさえ)、そこでxそれが起こる文句を言わないので、結果の後半に表示されます。後の衝突では、3番目の項も同じ場合にのみ平均は同じになりますが、最初の項の間の差は小さくなければ(同じでなければ)x、後のインデックスで検出されます。 。そのため、ṫ-Sṭµ¡i³¶ḶŒcÇÐṀ4バイトを節約できます。
ジョナサンアラン


@StewieGriffinそのテストケースは、私が:p
Erik the Outgolfer

1

GolfScript - 88 77バイト

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

cardboard_boxのおかげで、複数のソリューションをチェックしませんでした!

説明

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

バッチ、160 158バイト

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

これは(また)3 7入力を与えます27。正しい解決策は0 9です。
cardboard_box

@cardboard_box質問がそれを必要とする場所がまだ見られない...-
ニール

最初の文:「可能な最小の平均値で」。
cardboard_box

@cardboard_boxああ、すみません、見落としがちでした。
ニール

1
@cardboard_box OKが修正されました。
ニール
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.