フィボナッチパターンを見つける


16

おそらく、最初の2つの項が(または時々)フィボナッチ数列に精通しており、その後のすべての項は前の2つの項の合計です。次のように始まります。0, 11, 1

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

時々、シーケンスには、興味深いと思う特定のパターンを持つ数字が含まれています。隣接する数字のペアの違いは、他のペアと同じです。たとえば、で始まるシーケンスで0, 1は、18番目の項は987です。9-8=1および8-7=1。少し満足しています。

チャレンジ

2つの初期値F(0)とが与えられるとF(1)F(n) = F(n-1) + F(n-2)それによって生成されたシーケンス内のすべての数値を出力し、次の基準を満たします。

  • 隣接する数字のペアの違いは、他のペアと同じです
  • 少なくとも3桁の長さです(このパターンでは1桁と2桁の数字は関係ありません)

入力

  • 10 ** 10(100億)未満の2つの非負整数

出力

  • 10 ** 10未満で、チャレンジセクションの条件を満たすすべての整数
  • 10 ** 10を超える数字を出力することは可能ですが、必須ではありません
  • 繰り返される数字がパターン(例777)を満たす場合、基準を満たす無限の数字がある可能性がありますが、プログラムは永久に出力する必要はありません
  • そのような整数が存在しない場合は、数値でない限り何でも出力します(何も、null、空の配列、エラーメッセージ、悲しい顔など)
  • パターンに一致する数字がシーケンス内に複数回出現する場合、1回または発生した回数だけ出力できます。
  • 入力が基準を満たす場合、出力に含める必要があります

ルール

例/テストケース

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
推奨テストケース:[1976, 123] -> [123, 2222, 4321, 6543, 45678][3189, 826] -> [888888888][33345, 692] -> [987654321]
アルノー

@Arnauld素晴らしい発見!どの開始ペアが10B未満の最大出力値を持っているのでしょうか。それを超えるものはすべてrepdigitsであり、それは退屈です。
エンジニアトースト

@Arnauldテストケースの修正をありがとう。私のオリジナルのジェネレーターでは、入力を含めませんでした。戻ってそれらを追加したとき、私は明らかにこれらの2つを逃しました。
エンジニアトースト

回答:


9

MATL、14バイト

間違いを指摘してくれたエミグナに感謝します。

`yVdd~?yD]wy+T

見つかった数値を出力する無限ループ。

オンラインでお試しください!オンライン通訳では、1分のタイムアウト後に結果が表示されることに注意してください。

説明

ましょうF(n)F(n+1)フィボナッチ数列の一般的な2つの連続した用語を示します。ループの各反復は含むスタックで始まりF(n)F(n+1)いくつかのために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

05AB1E17 16 15バイト

тFÂ2£O¸«}ʒS¥¥_W

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

説明

                  # 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バイト

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

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

隣接する数字のテスト

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

xdは両方とも匿名関数に初期化さNaNれます。これsome()により(d = [function] - n) === NaN、関係するすべての算術演算が強制されます。最初の反復では、常にand (r = [function] - d) === NaN(偽)が返されます。2番目の反復では、d = x - n(整数)と(r = NaN - d) === NaN(再び偽)があります。3番目の反復から開始して、桁3と桁2の差が桁2と桁1の差と等しくない場合、rはゼロ以外の整数に設定されます。

数値pは、some()偽であり(隣接するすべての数字に同じ差がある)、rの最終値が0(少なくとも3回の反復があった)の場合にのみ、必要な基準を満たしています。これは!false / 0 === true / 0 === Infinity(真実)を提供します。

そうでない場合:

  • !true / rR> 0又はR <0が得られる、false / r === 0(falsy)
  • !false / NaNtrue / NaN === NaN(偽)を与える

停止状態

0p | q評価されると、再帰は停止します。これは、pqの両方が84ビット長の10 25前後の値に達したときに起こることが保証されています。JSには52ビットの仮数があるため、最後の32ビットはゼロになります。したがって、32ビットのビット単位のORは0と評価されます

シーケンスの急速な成長率により、これはかなり速く発生します。


4

ジャワ8、151の 144 140 136 130バイト

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

見つかったときに番号を出力する無限ループ。
オンラインで試してください(60秒後にタイムアウト)。

10 10の制限が追加された136バイトバージョン(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;}

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

説明:

(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

ゼリー20 19 18バイト

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

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

+ƝḢ;Ɗȷ¡ȷ常に十分なシリーズの最初の1000個の用語を生成します。おそらくもっと短い方法があると思います。+ȷ¡近くなりますが、最初の項がゼロの場合にのみ機能します。

私たちは1バイトを許す2つの数字を逆に取ることができると思っていますDIE

入力のいずれかを出力する必要がない場合:

ゼリー、15バイト

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

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


5
DIEƊゴルフの過程でのすべての大胆不敵なバイトに対する私たちの考え。
アーナウルド

4

オクターブ91 90 83バイト

ルイスメンドーのおかげで7バイト節約できました!

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

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

まあ、それは動作します!

evalforループを使用して、数バイトを節約します。コロンとセミコロンスキップしていくつかを節約します。すべての要素がゼロanyまたはゼロ以外で保存されている場合、ベクトルは真実であると見なされるという事実を使用しますall

それ以外は、フィボナッチの実装はかなり単純です。



2

Haskell、105バイト

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

(%)すべての解で無限リストを返す演算子を定義します。実際の結果を参照するには、標準出力、我々は無効にバッファリングする必要があります(またはそれを実行するghciかとのrunhaskell)、オンラインそれを試してみてください!

説明/ゴルフなし

この関数fは、バイナリ関数とリストを必要とする単なるヘルパー関数であり、gすべての隣接するペアに関数を適用します。基本的には次と同じです:

adjacent g xs = zipWith (tail xs) xs

演算子(%)は、いくつかのフィルタリングを行う単なるリスト内包表記です(少なくとも3桁あり、隣接する桁が同じ距離を持っていることを確認します)。

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バイト

q~{1$_99>"_`2\ew{{-}*}%""3,"?~_(+="0$p"*~;_@+_11_#<}g;;

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

私の最初のCJam提出は、非常に短いものではなく、とても楽しいものです。どんな提案でも大歓迎です!


知っておくといい、ヒントをありがとう!提出物を更新しました。
maxb

2

スタックス26 24 バイト

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

実行してデバッグする

説明

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.

私が望むほど短くはなく、おそらくもう少しゴルフができるかもしれませんが、うまくいきます。



1

ジュリア0.686の 81バイト

a<b=b>=0&&((n->n>99&&2>endof(∪(diff(digits(n))))&&println(n)).([a,b]);a+b<a+2b)

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

かなり簡単です-入力に少なくとも3桁(n>99)があるかどうかを確認し、数字の各桁ペアの差()を取得し、()それらの一意のセットdiff(digits(n))endof)の長さが1(つまり、すべての差)であることを確認します同じです)、その場合は番号を印刷します。与えられた両方の数値に対してこれを行い、次の2つの数値で関数を再帰的に呼び出します。

(のような残念ながら、それが見える±よりも高い優先順位を持っている+か、あるいは最後の呼び出しがされている可能性がa+b±a+2b3バイトを保存し、。)今、過負荷<ので、オペレータのバイトと優先順位ブラケットの両方に保存し、演算子を。(<ただし、コードでは使用できないため、再配置endof(...)<2します2>endof(...))。

いくつかの余分な出力が許可されている場合、我々は、使用して2つのバイトを保存することができます@show代わりにprintln印刷し、n = 987ちょうど代わりに987。それdumpよりも1バイト小さいdump値を使用することもできますが、値とともに型情報を出力するため、出力はのInt64 987代わりになり987ます。

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