デジタル合計フィボナッチ


30

私たちは皆、フィボナッチ数列に精通しています

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765

ただし、代わりに、前の2つのエントリのデジタル合計f(n) = f(n-1) + f(n-2)取得します。


シーケンスは引き続きで始まる必要があり0, 1、その後、違いはすぐに明らかになります。このリストには0のインデックスが付いていますが、1のインデックスも使用できます。

f(0)  = 0
f(1)  = 1
f(2)  = 1   # 0 + 1
f(3)  = 2   # 1 + 1
f(4)  = 3   # 1 + 2
f(5)  = 5   # 2 + 3
f(6)  = 8   # 3 + 5
f(7)  = 13  # 8 + 5
f(8)  = 12  # 8 + 1 + 3
f(9)  = 7   # 1 + 3 + 1 + 2
f(10) = 10  # 1 + 2 + 7
f(11) = 8   # 7 + 1 + 0
f(12) = 9   # 1 + 0 + 8
f(13) = 17  # 8 + 9
f(14) = 17  # 9 + 1 + 7
f(15) = 16  # 1 + 7 + 1 + 7
f(16) = 15  # 1 + 7 + 1 + 6
f(17) = 13  # 1 + 6 + 1 + 5
f(18) = 10  # 1 + 5 + 1 + 3
f(19) = 5   # 1 + 3 + 1 + 0
f(20) = 6   # 1 + 0 + 5
f(21) = 11  # 5 + 6
f(22) = 8   # 6 + 1 + 1
f(23) = 10  # 1 + 1 + 8
f(24) = 9   # 8 + 1 + 0
f(25) = 10  # 1 + 0 + 9
f(26) = 10  # 9 + 1 + 0
f(27) = 2   # 1 + 0 + 1 + 0
(After this point it repeats at the 3rd term, 0-indexed)

注:チャレンジ自体を投稿するまで繰り返しに気付かなかったため、ここで別の小説フィボナッチチャレンジを書くことは不可能だと考えていました。


タスクには、番号が与えられ、nこのシーケンスのn番目の桁が出力されます。

最初の3桁:[0,1,1]

24桁の繰り返しパターン: [2,3,5,8,13,12,7,10,8,9,17,17,16,15,13,10,5,6,11,8,10,9,10,10]

ヒント:この繰り返しを利用して、あなたの利益を得ることができます。


これは、最小のバイト数が勝者です。


ボーナス:回答で繰り返しを使用する場合、シーケンス内の繰り返しを利用して100ポイントの賞金を獲得する、最低バイト数の回答を授与します。これは、元の回答の後に、元の回答の一部として提出する必要があります。私が話していることの例として、この投稿を参照してください:https : //codegolf.stackexchange.com/a/108972/59376

このボーナスの資格を得るには、コードをO(1)説明付きで一定時間()で実行する必要があります。

ボーナス受賞者:デニスhttps://codegolf.stackexchange.com/a/108967/59376 <デニスが勝ちました。

最もユニークな実装:https : //codegolf.stackexchange.com/a/108970/59376
(また、正解が選択された後にファイナライズされた100ポイントを受け取ります)


2
1ベースのインデックスを使用できますか、それとも0ベースでなければなりませんか?
ビジネス猫

1
@BusinessCatええ、確かに、それをねじ込みます。
魔法のタコUr

1
どのように繰り返しを利用して定義しますか?ハードコーディングする必要があり%24ますか、それとも「通常の」ソリューションに追加するだけですか?
デニス

1
@Dennis私は、繰り返しを利用することを意味すると定義していますO(1)。繰り返しを本当に利用している場合、コードは一定の時間で実行されている必要があります。
魔法のタコUr

1
入力の@Dennisの技術的な%24は、27回の繰り返しで上限になります。興味深いことではありませんが、間違いなく重要です。
魔法のタコUr

回答:



28

JavaScript(ES6)、45バイト

f=(n,x=0,y=1)=>n?f(n-1,y,(x%9||x)+(y%9||y)):x
<input type=number min=0 oninput=o.textContent=f(this.value)><pre id=o>

xy両方をすることはできません9、それは前の数字があることを必要とする0ので、彼らのデジタル合計は超えられないから17です。これは、より大きい数値のデジタルルート9が剰余剰余と同じであることを意味し9ます。


6
これ、これは繰り返しリーダーに相当する賞金をもらえるでしょう...これは素晴らしい数学的な洞察です。
魔法のタコUr

13

Python 2、53バイト

f=lambda n:n>1and sum(map(int,`f(n-1)`+`f(n-2)`))or n

再帰関数。ベースのケースn=0n=1収率n、より大きな番号が呼び出すことによって値を計算f(n-1)し、f(n-2)使用して整数に各文字を変換する、2つの文字列を連結し、文字列にそれぞれ変換mapしてint機能し、その後、結果のリストを合計します。


modulo-24情報を使用すると、現在、56バイトの非再帰的な名前のない関数を取得できます。

lambda n:int(('011'+'2358dc7a89hhgfda56b8a9aa'*n)[n],18)

1
はい!+1 繰り返し答え:)。私はあなたの名誉addedにボーナスセクションを追加しました、あなたは今100ポイントの賞金コンテストのリーダーです!
魔法のタコUr

11

JavaScript(ES6)、34バイト

f=n=>n<2?n:~-f(--n)%9+~-f(--n)%9+2

27を超える入力ではブラウザがフリーズする場合がありますが、すべての入力値で機能します。これは単純なキャッシュで検証できます:

c=[];f=n=>n<2?n:c[n]=c[n]||~-f(--n)%9+~-f(--n)%9+2
<input type=number value=0 min=0 step=1 oninput="O.value=f(this.value)"> <input id=O value=0 disabled>

Neilのすばらしい回答で指摘されているように、出力は17を超えることはできないため、9を超える出力のデジタル合計はに等しくなりn%9ます。これは、9未満の出力でも機能します。~-モジュラスの前で1を減算し、その後1を加算して戻すことで、9でも機能させることができます。


ハードコーディングでできる最善の方法は50バイトです。

n=>"0x"+"7880136ba5867ffedb834968"[n%24]-(n<3)*9+2

6

ゼリー、8バイト

;DFS
ç¡1

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

使い方

ç¡1   Main link. No arguments. Implicit left argument: 0

  1   Set the right argument to 1.
ç¡    Repeatedly execute the helper link n times – where n is an integer read from
      STDIN – updating the left argument with the return value and the right
      argument with the previous value of the left argument. Yield the last result.


;DFS  Helper link. Arguments: a, b

;     Concatenate; yield [a, b].
 D    Decimal; convert both a and b to their base-10 digit arrays.
  F   Flatten the result.
   S  Compute the sum of the digits.

代替ソリューション、19バイト、一定時間

;DFS
9⁵ç23С⁸ịµṠ>?2

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

使い方

9⁵ç23С⁸ịµṠ>?2  Main link. Argument: n

9               Set the return value to 9
 ⁵              Yield 10.
  ç23С         Execute the helper link 23 times, with initial left argument 10
                and initial right argument 9, updating the arguments as before.
                Yield all intermediate results, returning
                [10,10,2,3,5,8,13,12,7,10,8,9,17,17,16,15,13,10,5,6,11,8,10,9].
   ⁸ị           Extract the element at index n. Indexing is 1-based and modular.
     µ          Combine all links to the left into a chain.
       >?2      If n > 2, execute the chain.
      Ṡ         Else, yield the sign if n.

1
「一定の時間内に繰り返されるセクション全体を計算しましょう」という内容の+1:D
Felix Dombek

4

JavaScript(ES6)、52 46 45バイト

_=$=>$<2?$:eval([..._(--$)+[_(--$)]].join`+`)

使用法

_=$=>$<2?$:eval([..._(--$)+[_(--$)]].join`+`)
_(7)

出力

13

説明

この関数は、入力が2より小さいかどうかを確認し、小さい場合は入力を返します。それ以外の場合は、文字列として相互に追加される2つの値の配列を作成します。これらの二つの値を持つ関数の呼び出しの結果であるinput - 1input - 2

...オペレータは、今と、再度文字列に変換された文字の配列にこの文字列を分割し+た値との間のES。次に、この文字列はコードとして解釈されるため、合計が計算されて返されます。

これは二重再帰アルゴリズムであり、非常に非効率的です。n-2入力には2つの関数呼び出しが必要nです。そのため、ここではより長いですがより高速なソリューションを紹介します。ETHproductionsを作成してくれてありがとう。

f=($,p=1,c=0)=>$?f($-1,c,eval([...p+[c]].join`+`)):c

この27のような大きな値のために動作しませんが、それは(少なくとも、それは私のためにありません)ブラウザをフリーズ
KritixiのLithos

しばらく時間がかかりますが、最終的にはそこに到達します... ...私はそれに見ていきますが、パフォーマンスはこの挑戦のために重要ではありません
ルーク

まあ、イエス、それは計算量がそれほど多くないので、あなたのプログラムは27を超える値で動作するはずです...
魔法のタコUr

1
@KritixiLithos問題は再帰です。シーケンス内のn番目の数を計算するには、おおよそ2 ^(n-2)個の関数呼び出しが必要です。
ETHproductions

あなたがバイトを保存することができます[..._(--$)+[_(--$)]]:-)
ETHproductions


3

CJam、22 20バイト

Martin Enderのおかげで2バイト節約

ri2,{(_(jAb\jAb+:+}j

単純な再帰アルゴリズム、空想なし。0インデックス。

オンラインでお試しください!または0〜50でテストします(実際にはかなり高速に実行されます)。

説明

ri                    Read an integer from input
  2,                  Push the array [0 1]
    {             }j  Recursive block, let's call it j(n), using the input as n and [0 1] as base cases
     (                 Decrement (n-1)
      _(               Duplicate and decrement again (n-2)
        jAb            Get the list digits of j(n-2)
           \           Swap the top two elements
            jAb        Get the list of digits of j(n-1)
               +       Concatenate the lists of digits
                :+     Sum the digits

CJam、42バイト

繰り返しを使用したソリューション。ジョナサンアランのソリューションと同様のアルゴリズム。

ri_2,1+"[2358DC7A89HHGFDA56B8A9AA]"S*~@*+=

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


3

Perl 6の 41  37バイト

{(0,1,{[+] |$^a.comb,|$^b.comb}...*)[$_]}

それを試してみてください

{(0,1,*.comb.sum+*.comb.sum...*)[$_]}

それを試してみてください

{ # bare block lambda with implicit parameter 「$_」
  (

    0, 1,           # first two values

    # WhateverCode lambda with two parameters ( the two 「*」 )
    *.comb.sum      # digital sum of first parameter
    +
    *.comb.sum      # digital sum of second parameter

    ...            # keep using that code object to generate new values until:

    *              # never stop

  )[ $_ ]          # index into the sequence
}

1
内側のラムダをとして書くことができます*.comb.sum+*.comb.sum
SMLS

2

MATL、15バイト

lOi:"yyhFYAss]&

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

lO       % Push 1, then 0. So the next generated terms will be 1, 1, 2,... 
i        % Input n
:"       % Repeat that many times
  yy     %   Duplicate top two elements in the stack
  h      %   Concatenate into length-2 horizontal vector
  FYA    %   Convert to decimal digits. Gives a 2-row matrix
  ss     %   Sum of all matrix entries
]        % End
&        % Specify that next function (display) will take only 1 input
         % Implicit display


2

C、96バイト

またはエスケープコードをそれぞれ1バイトとしてカウントする61バイト

0がインデックス付けされました。他の回答のいくつかと同様に、値のルックアップテーブルにインデックスを付けていますが、4バイトのチャンクに圧縮しています。私はmod 24バージョンの調査を気にしませんでした。なぜなら、他の人がすでにそうしているので、それがそれほど面白くないとは思わなかったからです。

#define a(n) n<3?!!n:2+(15&"\x1\x36\xba\x58\x67\xff\xed\xb8\x34\x96\x87\x88"[(n-3)/2%12]>>n%2*4)

説明:

#define a(n)                                                                                     // using a preprocessor macro is shorter than defining a function
             n<3?!!n:                                                                            // when n is less than 3 !!n will give the series 0,1,1,1..., otherwise..
                                                                             (n-3)/2%12          // condition the input to correctly index the string...
                           "\x1\x36\xba\x58\x67\xff\xed\xb8\x34\x96\x87\x88"                     // which has the repeating part of the series encoded into 4 bits each number
                                                                                                 // these are encoded 2 less than what we want as all numbers in the series after the third are 2 <= a(n>2) <= 17 which conforms to 0 <= a(n>2) - 2 <= 15
                                                                                        >>n%2*4  // ensure the data is in the lower 4 bits by shifting it down, n%2 will give either 0 or 1, which is then multiplied by 4
                        15&                                                                      // mask those bits off
                     2+                                                                          // finally, add 2 to correct the numbers pulled from the string

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


私はエスケープコードをそれぞれ1バイトとして数えます!素晴らしい仕事
アルバートレンショー



2

Mathematica、49バイト

If[#<2,#,Tr[Join@@IntegerDigits[#0/@{#-1,#-2}]]]&

簡単な再帰的定義。しばらくするとかなり遅くなります。

Mathematica、79 71バイト

If[#<3,Sign@#,(9@@LetterNumber@"JJBCEHMLGJHIQQPOMJEFKHJ")[[#~Mod~24]]]&

周期的パターンのハードコーディング。高速かつ満足のいくMathematicaへの虐待:) 8バイトを節約してくれたJungHwan Minに感謝します!


2番目のコードの場合LetterNumber@"JJBCEHMLGJHIQQPOMJEFKHJ"は、より8バイト短くなり43626804920391712116157158790~IntegerDigits~18ます。
ジョンファンミン

あなたが正しい!私が覚えているつもりだこれらの日のいずれかLetterNumber....
グレッグ・マーティン

1

Python 2、56バイト

シンプルな反復ソリューション。

a,b=0,1
exec'a,b=b,(a%9or a)+(b%9or b);'*input()
print a

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

(a%9or a)+(b%9or b)実際の使用は、sum(map(int(`a`+`b`)))


私はあなたの意味だと思うsum(map(int,a+b))(コメントで`使用する方法を見つけ出すことはできません)

1

PowerShell、79バイト

$b,$c=0,1;for($a=$args[0];$a;$a--){$z=[char[]]"$b$c"-join'+'|iex;$b=$c;$c=$z}$b

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

forループを直接数字合計計算する退屈な反復ソリューション。ループの終わりでは、必要な数値はin $bであるため、パイプラインに残り、出力は暗黙的です。入力された場合ことに注意してください0条件が偽であることからして、その後、ループは、入りません$bが残ります0


1

バッチ、85バイト

@set/ax=0,y=1
@for /l %%i in (1,1,%1)do @set/az=x-x/10*9+y-y/10*9,x=y,y=z
@echo %x%

JavaScriptの回答をバッチにどのように移植するのか疑問に思っていましたが、手がかりは@DennisのPythonソリューションにありました。


1

Pyth、20バイト

J,01VQ=+JssjRT>2J)@J

ゼロインデックス付き整数の入力を受け取り、結果を出力するプログラム。

テストスイート(フォーマットの最初の部分)

使い方

[後で説明する]


1

ルビー、58バイト

->n{n<3?n<=>0:"9aa2358dc7a89hhgfda56b8a"[n%24].to_i(18)}

シンプルなハードコーディングされたソリューション。



1

オクターブ、148バイト

function f = fib(n)
  if (n <= 1)
    f = n;
  else
    f = sum(int2str((fib(n - 1)))-48) + sum(int2str((fib(n - 2)))-48);
  endif
endfunction

ppcgへようこそ!素敵な最初の投稿!
Rɪᴋᴇʀ

1

Haskell、151バイト

import Numeric
import Data.Char
s i=foldr(\c i->i+digitToInt c)0$showInt i""
d a b=a:d b(s a+s b)
f 0=0
f 1=1
f 2=1
f i=d 2 3!!fromIntegral(mod(i-3)24)

f 123456789012345678901234567890123456789012345678たとえば、関数を呼び出します。

コードは非常に大きなインデックスでも機能します。Modulo 24機能が実装されているため、非常に高速です。

非圧縮コード:

-- FibonacciDigital
-- Gerhard
-- 13 February 2017

module FibonacciDigital () where

import Numeric
import Data.Char

-- sum of digits
digitSum :: Int -> Int 
digitSum i = foldr (\c i -> i + digitToInt c) 0 $ showInt i ""

-- fibonacci digital sequence function with arbitrary starting values
fibonacciDigitals :: Int -> Int -> [Int]
fibonacciDigitals a b = a : fibonacciDigitals b (digitSum a + digitSum b)

-- index -> fibonacci digital value
f :: Integer -> Int 
f 0 = 0 
f 1 = 1 
f 2 = 1 
f i = fibonacciDigitals 2 3 !! fromIntegral (mod (i-3) 24) 

-- End

0

R、90バイト

恐ろしく長い解決策ですが、それは私が最初に持っていた108よりも優れています。これを行うにはもっと良い方法があると思いますが、現時点ではわかりません。

function(n,x=0:1){repeat`if`(n,{x=c(x,sum(scan(t=gsub('',' ',x))))[-1];n=n-1},break);x[1]}

これは、使用しています無名の関数であるgsubscan(t=桁ベクター中の数字を分割します。これらの合計は、最初のアイテムがドロップされる間にベクトルに追加されます。 repeatシーケンスn時間をステップ実行するために使用され、結果はベクトルの最初の項目です。



0

Mathematica、67バイト

r=IntegerDigits;f@0=0;f@1=1;f[x_]:=f@x=Tr@r@f[x-1]+Tr@r@f[x-2];f@#&
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.