フィボナッチ化された除数を合計します!


14

有名なフィボナッチ数列はF(0) = 0; F(1) = 1; F(N+1) = F(N) + F(N-1)(このチャレンジでは0から始まります)です。

あなたの挑戦:考えるとnは、出力のすべての合計Dすべての除数のためのフィボナッチ数番目日間N番目のフィボナッチ数。より正式な表記を希望する場合は、

合計

入力:正の整数n

出力:合計

たとえば、検討してくださいn=4F(4) = 33の約数は1と3なので、出力はになるはずですF(1) + F(3) = 1 + 2 = 3

n=6F(6) = 8および8の除数1、2、4、8、であるので、出力されますF(1) + F(2) + F(4) + F(8) = 1 + 1 + 3 + 21 = 26

テストケース:

1 => 1
2 => 1
3 => 2
4 => 3
5 => 6
6 => 26

これは、バイト単位の最短回答が勝ちです。標準の抜け穴が適用されます。

回答:


2

実際には、5バイト

F÷♂FΣ

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

使い方

       (implicit) Read n from STDIN.
F      Compute F(n).
 ÷     Get F(n)'s divisors.
  ♂F   Map F over the divisors.
    Σ  Take the sum.

言語の名前は、受動的で攻撃的なように見えますが、それは意図したものですか?
ローハンジュンジュンワラ

1
疑わしい。言語の最初のバージョンはこのコメントのために真剣に呼ばれました。2番目のバージョンでは、著者は形容詞を使い続けることを選択しました。
デニス

6

ゼリー、7バイト

ÆḞÆDÆḞS

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

説明:

ÆḞÆDÆḞS Main link (Arguments: z)
ÆḞ      zth Fibonacci number's
  ÆD                           divisors'
    ÆḞ                                   Fibonacci numbers'
      S                                                     sum

絶対にとんでもない!私はこれらのエキゾチックな言語を知りませんが、いくつかの文字でアルゴリズム全体を書くことができるのは私にとって超自然的です。
ボグダンアレクサンドル

@BogdanAlexandruここで使用されている組み込み関数のほとんどは、1バイトに収まらないため、それぞれ2バイトを消費していることがわかります。さらに少ない文字については、デニスの実際の回答を参照してください。また、Jellyは「ゴルフの言語」であり、code-golf専用に作られた言語であり、ここでは最も効率的な言語の1つです(ただし、「最も効率的な」言語は1つではありません)。
エリックアウトゴルファー

これらの言語は実際には使用されておらず、チャレンジのみを目的としていると言っていますか?
ボグダンアレクサンドル


4

Mathematica Simplified、14バイト

Fi@#~Div9`~Fi&

まあ、これは@MartinEnderのソリューションと同じになりました...


まあ...同じ言語の短いバージョンを使用して...私はそれが動作すると思います。
ニールA.

Mathematicaには単一文字の関数名はありませんか?先頭の大文字と1バイトから構成される2つの文字列すべてに一致しませんか?もしそうなら、26 * 256 = 6656の単純化された2バイト関数名があり、300個の予備の6356 11.1.1名に十分です。
ジョナサンアラン

@JonathanAllanいいね。(ただし、次のような単一の名前関数がありますN
ジョンファンミン


2

05AB1E、11バイト

!ÅFDI<èÑ<èO

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

説明

!            # factorial of input
 ÅF          # get the list of fibonacci numbers (starting at 1)
             # smaller than or equal to this
   D         # duplicate list of fibonacci number
    I<è      # get the element at index (input-1)
       Ñ     # get the list of its divisors
        <    # decrement each
         è   # get the fibonacci numbers at those indices
          O  # sum


2

アリス38 36バイト

2バイトを節約してくれたLeoに感謝します。

/ow;B1dt&w;31J
\i@/01dt,t&w.2,+k;d&+

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

ほぼ確実に最適ではありません。制御フローはかなり複雑で、以前のバージョンで保存したバイト数に非常に満足していますが、もっと単純で短いソリューションます。

説明

最初に、Aliceのリターンアドレススタック(RAS)について少し詳しく説明する必要があります。他の多くのFungeoidと同様に、Aliceにはコード内をジャンプするコマンドがあります。ただし、元の場所に戻るコマンドもあるため、サブルーチンを非常に便利に実装できます。もちろん、これは2D言語なので、サブルーチンは実際には慣例によってのみ存在します。returnコマンド以外の方法(またはサブルーチン内の任意の時点)でサブルーチンを開始または終了することを妨げるものは何もありません。また、RASの使用方法によっては、とにかくきれいなジャンプ/リターン階層が存在しない場合があります。

一般に、これは、ジャンプコマンドを使用して、ジャンプjする前に現在のIPアドレスをRASにプッシュすることによって実装されます。次に、returnコマンドkはRASのアドレスをポップし、そこにジャンプします。RASが空の場合、k何もしません。

RASを操作する他の方法もあります。これらの2つは、このプログラムに関連しています。

  • wどこにジャンプすることなく、現在のIPアドレスをRASにプッシュします。このコマンドを繰り返すと、単純なループをとして非常に便利に書くことができ&w...kます。
  • Jのようなものですjが、RASの現在のIPアドレスを覚えていません

また、RAS はIPの方向に関する情報を保存しないことに注意することも重要です。アドレスに戻るので、k常に保持されます、現在にかかわらず、我々が通過したかの(私たちは枢機卿または序モードにいるかどうかもそのためと)IP方向をjw、最初にIPアドレスプッシュした。

それが終わったら、上記のプログラムのサブルーチンを調べてみましょう。

01dt,t&w.2,+k

このサブルーチンは、スタックの一番下の要素nを一番上に引き出し、フィボナッチ数F(n)F(n + 1)を計算しますスタックの一番上に残します)。F(n + 1)は必要ありませんが、&w...kループがRASと対話する方法により、サブルーチンの外で破棄されます(これらのループはサブルーチンの最後にある必要があります)。上部ではなく下部から要素を取得する理由は、スタックをキューのように扱うことができるためです。つまり、フィボナッチ数を他の場所に保存せずに一度に計算できます。

このサブルーチンの仕組みは次のとおりです。

                                                          Stack
01    Push 0 and 1, to initialise Fibonacci sequence.     [n ... 0 1]
dt,   Pull bottom element n to top.                       [... 0 1 n]
t&w   Run this loop n times...                            [... F(i-2) F(i-1)]

  .     Duplicate F(i-1).                                 [... F(i-2) F(i-1) F(i-1)]
  2,    Pull up F(i-2).                                   [... F(i-1) F(i-1) F(i-2)]
  +     Add them together to get F(i).                    [... F(i-1) F(i)]

k     End of loop.

ループの終わりには少し注意が必要です。スタックに「w」アドレスのコピーがある限り、これは次の反復を開始します。それらが使い果たされると、結果はサブルーチンの起動方法に依存します。サブルーチンが「j」で呼び出された場合、最後の「k」がそこに戻るため、ループの終わりはサブルーチンの戻りとして2倍になります。サブルーチンが 'J'で呼び出されたが、スタックの以前のアドレスがまだある場合は、そこにジャンプします。つまり、サブルーチンが外部ループ自体で呼び出された場合、この「k」はその外部ループの先頭に戻ります。サブルーチンが「J」で呼び出されたが、現在RASが空の場合、この「k」は何もせず、IPはループの後に移動し続けます。これらの3つのケースすべてをプログラムで使用します。

最後に、プログラム自体について説明します。

/o....
\i@...

これらは、10進整数の読み取りと印刷を行うための序数モードへの2つの簡単なエクスカーションです。

の後に、サブルーチンに渡される前に現在の位置を記憶iするがwあります/。サブルーチンのこの最初の呼び出しは、計算F(n)F(n+1)入力でn。その後、ここに戻りますが、現在は東に移動しているため、残りのプログラム演算子はCardinalモードになります。メインプログラムは次のようになります。

;B1dt&w;31J;d&+
        ^^^

ここ31Jに、サブルーチンへの別の呼び出しがあり、したがってフィボナッチ数を計算します。

                                              Stack
                                              [F(n) F(n+1)]
;     Discard F(n+1).                         [F(n)]
B     Push all divisors of F(n).              [d_1 d_2 ... d_p]
1     Push 1. This value is arbitrary.        [d_1 d_2 ... d_p 1]
      The reason we need it is due to
      the fact that we don't want to run
      any code after our nested loops, so
      the upcoming outer loop over all
      divisors will *start* with ';' to
      discard F(d+1). But on the first
      iteration we haven't called the
      subroutine yet, so we need some 
      dummy value we can discard.
dt&w  Run this loop once for each element     [d_1 d_2 ... d_p 1]
      in the stack. Note that this is once    OR
      more than we have divisors. But since   [d_i d_(i+1) ... F(d_(i-1)) F(d_(i-1)+1)] 
      we're treating the stack as a queue,
      the last iteration will process the 
      first divisor for a second time. 
      Luckily, the first divisor is always 
      1 and F(1) = 1, so it doesn't matter 
      how often we process this one.

  ;     Discard the dummy value on the        [d_1 d_2 ... d_p]
        first iteration and F(d+1) of         OR
        the previous divisor on subsequent    [d_i d_(i+1) ... F(d_(i-1))]
        iterations.
  31J   Call the subroutine without pushing   [d_(i+1) ... F(d_i) F(d_i+1)]
        the current address on the RAS.
        Thereby, this doubles as our outer
        loop end. As long as there's an
        address left from the 'w', the end
        of the subroutine will jump there
        and start another iteration for the
        next divisor. Once that's done, the
        'k' at the end of the subroutine will
        simply do nothing and we'll continue
        after it.

;     Discard the final F(d_i+1).
d&+   Get the stack depth D and add the top   [final result]
      D+2 values. Of course that's two more
      than we have divisors, but the stack is
      implicitly padded with zeros, so that
      doesn't matter.

1

公理、68バイト

g==>fibonacci;f(x:NNI):NNI==(x<3=>1;reduce(+,map(g,divisors(g(x)))))

いくつかのテスト

(46) -> [[i,f(i)] for i in [0,1,2,3,4,5,6,10,15] ]
   (46)
   [[0,1], [1,1], [2,1], [3,2], [4,3], [5,6], [6,26], [10,139583862540],
     [15,
      135823697912782666169062844948067355657769395021071830756126284114988028_
       12823029319917411196081011510136735503204397274473084444
     ]
   ]
                                       Type: List List NonNegativeInteger



1

R、77バイト

F=gmp::fibnum;N=F(scan());i=n=N-N;while(i<N)if(N%%(i=i+1)<1)n=n+F(i);print(n)

「gmp」ライブラリを使用します。これには組み込みのフィボナッチ関数があり、大きな数を実行する機能を提供します。それは、seqsとapplysでいくつかの問題を引き起こしましたが、私自身のフィボナッチ関数を作成するよりはまだ小さいです。

説明

F=gmp::fibnum;               # Set F as fibnum function
N=F(scan());                 # get input and set N to the fibonacci number of that index
i=n=N-N;                     # set i and n to 0 with data type bigz
while(i<N)                   # loop while i < N
   if(N%%(i=i+1)<1)          # if incremented i is divisor of N 
       n=n+F(i);             # add F(i) to rolling sum
print(n)                     # output final result

テスト

> F=gmp::fibnum;N=F(scan());i=n=N-N;while(i<N)if(N%%(i=i+1)<1)n=n+F(i);print(n)
1: 6
2: 
Read 1 item
Big Integer ('bigz') :
[1] 26
> F=gmp::fibnum;N=F(scan());i=n=N-N;while(i<N)if(N%%(i=i+1)<1)n=n+F(i);print(n)
1: 10
2: 
Read 1 item
Big Integer ('bigz') :
[1] 139583862540
> F=gmp::fibnum;N=F(scan());i=n=N-N;while(i<N)if(N%%(i=i+1)<1)n=n+F(i);print(n)
1: 15
2: 
Read 1 item
Big Integer ('bigz') :
[1] 13582369791278266616906284494806735565776939502107183075612628411498802812823029319917411196081011510136735503204397274473084444

gmpを使用しない

81バイト、大きな(9+)の数字が選択されたときに絶望的に遅い再帰関数

F=function(n)`if`(n<2,n,F(n-1)+F(n-2));sum(sapply(which((N=F(scan()))%%1:N<1),F))

88バイト、ビネットの式は大きな数値でも十分に機能しますが、整数の制限にすぐに到達します

F=function(n)round(((5+5^.5)/10)*((1+5^.5)/2)^(n-1));sum(F(which(F(N<-scan())%%1:N<1)))


0

CJam、26バイト

qi_[XY@{_2$+}*]_@\f%:!.*:+

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

もっと良くできると確信しています。説明:

フィボナッチ数の配列を作成し、その数が入力の約数である場合とそうでない場合に1と0の配列をドット積するという考え方です。

qi                                 Read the input (n)
   [XY        ]                    Array starting with [1,2,...]
  _   @{_2$+}*                     Append n times the sum of the previous two
               _                   Duplicate the array
                @\f%               Modulo each item with n (0 if divisor, a number otherwise)
                    :!             Logical NOT everything (1 if divisor, 0 otherwise) 
                      .*:+         Dot product those two arrays

0

JavaScript(ES6)、76 65バイト

f=(n,i=k=(F=n=>n>1?F(n-1)+F(n-2):n)(n))=>i&&(k%i?0:F(i))+f(n,i-1)

テストケース


0

JavaScript(ES6)、105 104 103 101 97バイト

i=>[...Array((g=(n,x=0,y=1)=>n--?g(n,y,x+y):x)(i)+1)].map((_,y)=>s+=g((z=g(i)/y)%1?0:z|0),s=0)&&s

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

f=
i=>[...Array((g=(n,x=0,y=1)=>n--?g(n,y,x+y):x)(i)+1)].map((_,y)=>s+=g((z=g(i)/y)%1?0:z|0),s=0)&&s
o.innerText=f(j.value=4)
oninput=_=>o.innerText=f(+j.value)
<input id=j type=number><pre id=o>


私は考えてあなたが変更することができます(z=g(i)/y)>~~z(z=g(i)/y)%1、あなただけのことはチェックしている場合は、z整数です。
ETHproductions

@ETHproductionsに変更g(z)することで解決できるオーバーフローを作成しますがg(z|0)、同じバイトカウントに戻します。
シャギー



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