繰り返しフィボナッチ桁とは何ですか?


30

おそらくご存知のように、フィボナッチ数は、シリーズの前の2つの数の合計です。

Fibonacci Digit™は、前の2つの数字の合計です。

たとえば、シリーズの開始の1,1場合、シリーズはになります1,1,2,3,5,8,13,4,7,11,2...。変更はの後に発生し、追加する13代わりにを追加8+13します1+3。シリーズは最後にループします。ここで4+7=11、および1+1=2は、シリーズの開始と同じです。

別の例として、シリーズの始まり2,22,2,4,6,10,1,1,2,3,5,8,13,4,7,11,2,3...。これは一意に始まりますが、数字が合計する101+0=1, 0+1=1になり、シリーズはシリーズと同じように継続し、ループ1,1します。


チャレンジ

整数入力が与えられた場合0≤n≤99、これらの2桁で始まるフィボナッチ桁シリーズのループを計算します。(あなたは確かにこの範囲外の整数を考慮許可されていますが、必須ではありません。)1桁の入力が与えられた場合、コードはそれを解釈してシリーズ開始を示し0,nます。

ループ内の2桁の数値はすべて、2桁として出力する必要あります。そのため、たとえば、ループforに1,1はが含まれますが13、ではありません1,3

出力は、ループの最初の番号から始まります。したがって、上記の制限に基づいて、のループはで1,1始まる2ため1,111は別々にカウントされます。

出力の各番号は、一貫している限り、必要に応じて区切ることができます。すべての例でコンマを使用していますが、常に同じ区切り文字を使用している限り、スペース、改行、ランダムな文字などはすべて許可されます。の2g3g5g8g13g4g7g11正当な出力もありますが12j3g5i8s13m4g7sk11ではありません。一貫したセパレータで区切られた正しい順序で正しい番号を持っている限り、文字列、リスト、配列などを使用できます。出力全体を角括弧で囲むこともできます(例:(5,9,14)または[5,9,14]など)。

テストケース:

1 -> 2,3,5,8,13,4,7,11
2 -> 2,3,5,8,13,4,7,11
3 -> 11,2,3,5,8,13,4,7
4 -> 3,5,8,13,4,7,11,2
5 -> 2,3,5,8,13,4,7,11
6 -> 3,5,8,13,4,7,11,2
7 -> 14,5,9
8 -> 13,4,7,11,2,3,5,8
9 -> 11,2,3,5,8,13,4,7
0 -> 0
14 -> 5,9,14
59 -> 5,9,14

これはであるため、最小のバイト数が優先されます。


1
我々は代わりに、入力として2桁の数字を取ることができます0n99
アーナウルド

1
たとえば、分割された1つの入力ではなく2つの入力を使用しますか?いいえ
ドニエルF

私はまだ理由14を理解していないし59、同じ結果を与えます。59が開始され5,9、ループの一部としてそれを許可すると解釈される場合、確実にループ14の開始になるはずですか?
ニール

1
@williamporterシーケンスの始まりは0,1,1,2,3,5,8,13,4,7,11,2,3です。ループが最初に繰り返されるのは2番目2です。
ドニエル

2
それらのそれぞれのシーケンスの始まり@Neilである1,4,5,9,14,55,9,14,5,9。両方とも2番目から繰り返し5ます。前述したように、入力のみが分割されます。後の数字は、数字を順番に並べます。
ドニエル

回答:


10

ゼリー、15バイト

DFṫ-SṭḊ
d⁵ÇÐḶZḢ

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

使い方

d⁵ÇÐḶZḢ  Main link. Argument: n (integer)

d⁵       Divmod 10; yield [n:10, n%10].
  ÇÐḶ    Call the helper link until a loop is reached. Return the loop.
     Z   Zip/transpose the resulting array of pairs.
      Ḣ  Head; extract the first row.


DFṫ-SṭḊ  Helper link. Argument: [a, b] (integer pair)

D        Decimal; replace a and b with the digits in base 10.
 F       Flatten the resulting array of digit arrays.
  ṫ-     Tail -1; take the last two digits.
    S    Compute their sum.
      Ḋ  Dequeue; yield [b].
     ṭ   Append the sum to [b].

6

Perl 6の96の78 75バイト

nwellnhofのおかげで-3バイト

{0,|.comb,((*~*)%100).comb.sum...{my$a=.tail(2);m/(\s$a.*)$a/}o{@_};$_&&$0}

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

0は0を返し、他の数字は、スペースで区切られた数字に文字列化されたMatchオブジェクトを返します。

説明:

{                                                                         }   # Anonymous code block
 0,|.comb,                    ...   # Start a sequence with 0,input
                                    # Where each element is
                          .sum      # The sum of
          (     %100).comb          # The last two digits
           (*~*)                    # Of the previous two elements joined together
                                                                         # Until
                                 {                           }o{@_}   # Pass the list into another function
                                  my$a=.tail(2); # Save the last two elements
                                                m/(\s$a.*)$a/  # The list contains these elements twice?
                                                                     # And return
                                                                   ;$_     # Input if input is 0
                                                                      &&   # Else
                                                                        $0 # The looping part, as matched

5

JavaScript(ES6)、 111 104  103バイト

f=(n,o=[p=n/10|0,n%10])=>n^o[i=o.lastIndexOf(n=(q=p+[p=n])/10%10+q%10|0)-1]?f(n,[...o,n]):o.slice(i,-1)

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

コメント済み

f = (                       // f = recursive function taking:
  n,                        //    n = last term, initialized to the input
  o = [                     //    o = sequence, initially containing:
    p = n / 10 | 0,         //      p = previous term, initialized to floor(n / 10)
    n % 10 ]                //      n mod 10
) =>                        //
  n ^                       // we compare n against
  o[                        // the element in o[] located at
    i = o.lastIndexOf(      //   the index i defined as the last position of
      n =                   //     the next term:
        (q = p + [p = n])   //       q = concatenation of p and n; update p to n
        / 10 % 10           //       compute the sum of the last two digits
        + q % 10            //       of the resulting string
        | 0                 //       and coerce it back to an integer
      ) - 1                 //   minus 1
  ] ?                       // if o[i] is not equal to n:
    f(n, [...o, n])         //   append n to o[] and do a recursive call
  :                         // else:
    o.slice(i, -1)          //   we've found the cycle: return it

5

Pythonの3187 176 158 139 138 129 121 120 112の 96 95 120 116バイト

f=lambda n,m=0,z=[]:(n,m)in zip(z,z[1:])and z[z.index(m)::-1]or f((z and n//10or m%10)+n%10,z and n or n//10,(m,*z))

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

編集:@ Julesが述べたように、短いソリューションはPython 3.6+に適用されます。Python 3 / 3.6+向けの個別のソリューションではなくなりました

編集:のインデックス作成はz冗長すぎました。それなしでは、今では使用するメリットはありませんeval

編集:最後の2つの要素が既にシーケンスに表示されている場合の検索結果を簡素化しました。

編集:リストから変更し、出力形式タプルに+置き換えるlambdadef

編集:に戻るlambdaが埋め込まtれているf

編集:入力nは実際にはz、再帰的アプローチのテールを表す成長中のコレクションのヘッドとして解釈できます。また、@ Arboのソリューションを再び破りました。

編集:実際には、ヘッドから2つのアイテムをアンパックして、さらに16バイトをカットできます。

編集:実際には17バイト。

編集:としては、@で述べARBOのソリューションがための答え与えていた1459、彼らは後に間違っていることが証明された最初のテストケースにあったような場合に。今のところ、これはそれほど短くはありませんが、少なくとも正しく動作します。


かなりの乱用f-stringseval。オリジナルのコードなしのコードですが、どういうわけか簡単にできると思われます。

def is_subsequence(l1, l2):
    N, n = len(l1), len(l2)
    for i in range(N-n):
        if l1[i:i+n]==l2:
            return True
    return False

def generate_sequence(r):
    if is_subsequence(r,r[-2:]):
        return r
    last_two_digits = "".join(map(str,r))[-2:]
    new_item = sum(int(digit) for digit in last_two_digits)
    return generate_sequence(r + [new_item])

def f(n):
    seq = generate_sequence([n,n])[::-1]
    second_to_last = seq[1]
    first_occurence = seq.index(second_to_last)
    second_occurence = seq.index(second_to_last, first_occurence + 1)
    return seq[first_occurence + 1 : second_occurence + 1][::-1]

1
小さな修正:これはPython 3.6以降です。これは明らかに3.5以前では機能しません。
0xdd

1
テストコードが機能しないようです。59利回りの入力(14, 5, 9)
ArBo

チャレンジを開始してからテストケースが変更されたため、出力が正しくありませんでした。解決策を変更して機能するようにしましたが、現時点ではそれほど短くはありません。それでも、それを指摘してくれてありがとう。
西岡

4

C(gcc)114 112 109バイト

f(n,s){int i[19]={};for(s=n/10,n%=10;i[s]-n;n+=n>9?-9:s%10,s=i[s])i[s]=n;for(;printf("%d ",s),i[s=i[s]]-n;);}

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

-3からceilingcat

末尾のスペースが含まれます。

f(n,s){
    int i[19]={};                               //re-initialize edges for each call
    for(s=n/10,n%=10;                           //initialize from input
        i[s]-n;                                 //detect loop when an edge s->n repeats
        n+=n>9?-9:s%10,s=i[s])i[s]=n;           //step
    for(;printf("%d ",s),i[s=i[s]]-n;);         //output loop
}

1
ハァー、do...while単一ステートメントO_oの場合は中括弧は必要ありません
ASCIIのみ



2

Haskell、100バイト

d!p@(s,t)|(_,i:h)<-span(/=p)d=fst<$>i:h|q<-d++[p]=q!(t,last$mod s 10+t:[t-9|t>9])
h x=[]!divMod x 10

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

d!p@(s,t)                -- function '!' recursively calculates the sequence
                         -- input parameter:
                         -- 'p': pair (s,t) of the last two numbers of the sequence
                         -- 'd': a list of all such pairs 'p' seen before
  |       <-span(/=p)d   -- split list 'd' into two lists, just before the first
                         -- element that is equal to 'p'
   (_,i:h)               -- if the 2nd part is not empty, i.e. 'p' has been seen
                         -- before
          =fst<$>i:h     -- return all first elements of that 2nd part. This is
                         -- the result.
  |q<-d++[p]             -- else (p has not been seen) bind 'q' to 'd' followed by 'p'
   =q!                   -- and make a recursive call to '!' with 'q' and
     (t,    )            -- make the last element 't' the second to last element
                         -- the new last element is
          [t-9|t>9]      -- 't'-9 (digit sum of 't'), if 't'>9
       mod s 10+t        -- last digit of 's' plus 't', otherwise

h x=                     -- main function
     []!divMod x 10      -- call '!' with and empty list for 'd' and
                         -- (x/10,x%10) as the pair of last numbers

2

パイソン2123の 114 113バイト

n=input()
p=b=l=n/10,n%10
while~-(b in p):p+=b,;l+=(b[1]/10or b[0]%10)+b[1]%10,;b=l[-2:]
print l[p.index(b)-2:-2]

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

このプログラムはp、シーケンスで発生したすべての2値ペアのタプルを構築します。これは、いくつかのバイトを節約するためにジャンクで初期化されます。シーケンス自体はtuple lに組み込まれ、このtupleの最後の2つの要素はb、簡単な(および短い)参照のために格納されます。すぐにリピートが見つかったとして、我々はインデックス調べることができますbでのp、ループがどこから始まったかを知る。

編集:これを少しクリーンアップし、もう1バイト削りました...私のメソッドはそのバイトカウント制限に近づいているようです。


1

、46バイト

≔E◧S²ΣιθW¬υ≔ΦE⊖L⊞OθΣ…⮌⪫θω²✂θλLθ¹⁼κ✂θ⊗⁻λLθλ¹υIυ

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

≔E◧S²Σιθ

数字を入力し、2文字にパディングしてから、各文字のデジタル合計を取り、結果のリストを保存します。

W¬υ

ループのリストが空の間、繰り返します。

⊞OθΣ…⮌⪫θω²

前の2桁の合計を計算し、フィボナッチリストに追加します。

E⊖L...✂θλLθ¹

リストの重要な接尾辞をすべて取ります。

≔Φ...⁼κ✂θ⊗⁻λLθλ¹υ

繰り返さないものを除外し、結果をループのリストに保存します。

Iυ

ループのリストを文字列にキャストして出力します。



1

Pythonの2149の 139バイト

s=input()
s=[s/10,s%10]
while zip(s,s[1:]).count((s[-2],s[-1]))<2:s+=[(s[-1]/10or s[-2]%10)+s[-1]%10]
print s[-s[::-1].index(s[-2],2)-1:-2]

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

入力として負でない整数を期待します。小さいバイト数ですが、99を超える整数では動作しなくなる可能性があります。

説明:

# get the input from STDIN
s=input()
# convert the input into two integers via a divmod operation
s=[s/10,s%10]
# count number of times the last two numbers appear in sequence in list.
# turn list into list of adjacent value pairs Ex: [1,1,2]->[(1,1),(1,2)]
      zip(s,s[1:])
                  # count number of times the last two items in list appear in entire list
                  .count((s[-2],s[-1]))
# if >1 matches, we have found a repeat.
while .................................<2:
        # the first digit of the last number, if it is >9
        # else the last digit of the second to last number
        (s[-1]/10or s[-2]%10)
                             # the last digit of the last number
                             +s[-1]%10
    # add the new item to the list
    s+=[..............................]
         # reverse the list, then find the second occurrence of the second to last item
         s[::-1].index(s[-2],2)
# get the section of the list from the second occurrence from the end, discard the final two items of the list
print s[-......................-1:-2]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.