ルーカスナッチ数


19

バックグラウンド

ほとんどの人はフィボナッチ数に 精通していますF(n)

0、1、1、2、3、5、8、13、21 ...

これらは、再帰関数によって形成されているF(n) = F(n-1) + F(n-2)F(0)=0してF(1)=1A000045

密接に関連するシーケンスはルーカス番号 L(m)です:

2、1、3、4、7、11、18、29 ...

これらは、再帰関数によって形成されているL(m) = L(m-1) + L(m-2)L(0)=2してL(1)=1A000032

我々は、構造と、偶数/奇数インデックスに基づいて、2つの配列の間で交互することができる
A(x) = F(x)場合x mod 2 = 0A(x) = L(x)そうでありません。たとえば、A(4)F(4)since と等しい4 mod 2 = 0です。私たちは、このシーケンスを呼ぶだろうルーカス・nacci番号A(x)

0、1、1、4、3、11、8、29、21、76 ...

これは、再帰関数を用いて形成することができるA(x) = 3*A(x-2) - A(x-4)とともにA(0)=0A(1)=1A(2)=1、とA(3)=4A005013

チャレンジ

inputが与えられるとn、上記のようn+1に、それを含む一連の数値を出力しますA(n)。最少バイト(または、Metaで個別に決定される、LabVIEWなどのバイト相当)が勝ちます。

入力

単一の非負整数n

出力

数字のリストからルーカス- nacci数のサブシーケンスに対応するようA(0)A(n)。上記のように、リストは順番に並んでいる必要があります。

ルール

  • 標準のコードゴルフ規則と抜け穴の制限が適用されます。
  • 標準の入出力ルールが適用されます。
  • 入力番号は、単項または10進数、STDINからの読み取り、関数またはコマンドライン引数など、任意の適切な形式にすることができます-選択。
  • 出力は、STDOUTに出力するか、関数呼び出しの結果として返すことができます。印刷する場合は、数字を区別するための適切な区切り文字を含める必要があります(スペース区切り、コンマ区切りなど)。
  • さらに、STDOUTへの出力の場合、周囲の空白、末尾の改行などはすべてオプションです。
  • 入力が非整数または負の整数である場合、動作は定義されていないため、プログラムは何でも実行できます。

Input -> Output
0 -> 0
5 -> 0, 1, 1, 4, 3, 11
18 -> 0, 1, 1, 4, 3, 11, 8, 29, 21, 76, 55, 199, 144, 521, 377, 1364, 987, 3571, 2584

改行は受け入れられた区切り文字と見なされますか?
corsiKa

@corsiKa確かに、それは結構です。
-AdmBorkBork

回答:


9

ゼリー、12バイト

;2U+¥Ð¡-,1ZḢ

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

バックグラウンド

F(-1)= 1およびL(-1)= -1を定義することにより、FおよびLを-1に拡張できます。これは、再帰関数と一致しています。

私たちのプログラムは

-1  1
 0  2

各ステップでは、次のペアを形成するために、最後のペアを逆にして最後から2番目のペアに追加します。例えば:

[0, 2] U+¥ [-1, 1] -> [2, 0] + [-1, 1] -> [1, 1]

このプロセスをさらに数ステップ続けると、

-1  1
 0  2
 1  1
 1  3
 4  2
 3  7
11  5

Lucas-nacciシーケンスは、単に左の列です。

使い方

;2U+¥Ð¡-,1ZḢ  Niladic link. No implicit input.
              Since the link doesn't start with a nilad, the argument 0 is used.

;2            Concatenate the argument with 2, yielding [0, 2].
       -,1    Yield [-1, 1]. This is [L(-1), F(-1)].
    ¥         Create a dyadic chain of the two atoms to the left:
  U             Reverse the left argument.
   +            Add the reversed left argument and the right one, element-wise.
     С       For reasons‡, read a number n from STDIN.
              Repeatedly call the dyadic link U+¥, updating the right argument with
              the value of the left one, and the left one with the return value.
              Collect all intermediate results.
          Z   Zip the list of results, grouping the first and seconds coordinates.
           Ḣ  Head; select the list of first coordinates.

С左側の2つのリンクを見てください:2U+¥。一番左のものはniladであるため、ループの本体になることはできません。したがって、U+¥はbodyとして使用され、入力から数値が読み取られます。コマンドライン引数がないため、その番号はSTDINから読み取られます。


2
私はあなたがこの種のこと(ゼリーでのゴルフ)を生計のためにしているという印象を受けます。それは私を恐れさせます。
Draco18s

24
誰かが生計のためにゴルフ(コード)をする方法を整理するなら、チャットで私にpingを送ってください。...友人のために頼む
マーティン・エンダー

2
したがって、基本的には両方のシーケンスを計算するだけですが、各ステップで逆になり、シーケンスを効果的に切り替えます。
ニール

1
@Neilはい、正確に。その後のシーケンスのインターリーブを回避しますが、これは少し長くなります。
デニス

6

CJam、21 20バイト

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

TXX4ri{1$3*4$-}*?;]p

ここでテストしてください。

説明

チャレンジ仕様で指定された繰り返しを使用します。

TXX4 e# Push 0 1 1 4 as base cases.
ri   e# Read input and convert to integer N.
{    e# Run this N times...
  1$ e#   Copy a(n-2).
  3* e#   Multiply by 3.
  4$ e#   Copy a(n-4).
  -  e#   Subtract.
}*
?;   e# Discard the last three values, using a ternary operation and popping the result.
]p   e# Wrap the rest in an array and pretty-print it.

1
すべての回答に感謝するSp3000は誰(または何)ですか?
CJデニス


5
@CJDennisある人は、彼がこれまでで最高のPythonゴルファーだと言います。彼は、山の頂上にある人里離れた小屋に住んでおり、最小限の丸太で建てられていると言う人もいます。彼は私たちの頭の後ろの声だと言う人もいます。しかし、私たちのほとんどは、彼がマーティンがリンクしているユーザーだと言っています。
メゴ

6

Perl 6、42バイト

{(0,1,1,4,{$^b;$^d;3*$^c-$^a}...*)[0..$_]}

使用法

> my &f = {(0,1,1,4,{$^b;$^d;3*$^c-$^a}...*)[0..$_]}
-> ;; $_? is raw { #`(Block|184122176) ... }
> f(0)
(0)
> f(5)
(0 1 1 4 3 11)
> f(18)
(0 1 1 4 3 11 8 29 21 76 55 199 144 521 377 1364 987 3571 2584)

1
私が思いついた最も明確なラムダは{( (0,1,*+*...*) Z (2,1,*+*...*) ).flat.rotor( 1=>2, 1=>0 )[ 0..$_ ].flat}
ブラッドギルバートb2gills

正確な表現が「指定されたn」であることを考えると、次のようにしてバイトを保存できます(0,1,1,4,{$^b;$^d;3*$^c-$^a}...*)[^(n+1)]
レイフ

6

ハスケル、59575652、51のバイト

l a=2*mod a 2:scanl(+)1(l a)
f n=[l i!!i|i<-[0..n]]

この回答から適応されたシリーズの定義。

少ないゴルフ:

fibLike start = start : scanl (+) 1 (fibLike start)
whichStart i = (2*mod i 2)
lucasNacci i = fibLike (whichStart i) !! i
firstN n = [ lucasNacci i | i <- [0..n]]

fibLike start定義された無限リストを提供しますf(0)=start, f(1)=1, f(n)=f(n-1) + f(n-2)whichStart i入力が奇数の場合は2(ルーカスシリーズ)、偶数の場合は0(フィボナッチシリーズ)を返します。 lucasNacci ii番目のルーカスナッチ数を返します。 firstN nリストにマップします。

Boomerangによって保存された1バイト。


1
に移動2*mod i 2してもう1バイト取得できると思いますl。その後、括弧を削除できます。このように:l a=2*mod a 2:scanl(+)1(l a)およびf n=[l i!!i|i<-[0..n]]
バジルヘンリー

@Boomerang Yup、それは動作します。ありがとう
マイケルクライン

5

ES6、65バイト

n=>[...Array(n)].map(_=>a.shift(a.push(a[2]*3-a[0])),a=[0,1,1,4])

質問で指定された繰り返し関係を使用します。


5

網膜70 62 59バイト

1
¶$`1
m`^(11)*1$
$&ff
m`$
 f
+`1(f*) (f*)
$2 $2$1
 f*

f
1

オンラインで試す

  • 入力は単項ベース、n 1です。
  • 1? $`¶-0からnまでの各番号の行を作成します。 , 1, 11, 111, 1111, ...
  • m`^(11)*1$ $&ff- ff奇数行に追加します。これにより、L(0)= 2の関数がシードされます。
  • m`$  f-  fすべての行に追加します(スペースに注意してください)。これにより、フィボナッチ数の場合は0と1、ルーカス数の場合は2と1の関数がシードされます。
  • +`1(f*) (f*) $2 $2$1 -ループ:1がまだある間にF(n + 1)= F(n)+ F(n-1)を計算します。
  •  f*   -各行の末尾からF(n + 1)を削除します。
  • fsを1に置き換えます。これが必要でなく、fsのままでよい場合、長さはわずか55バイトです。

5

Oracle SQL 11.2 218 216 201バイト

WITH v(a,b,c,d,i)AS(SELECT 0,1,1,4,3 FROM DUAL UNION ALL SELECT b,c,d,3*c-a,i+1 FROM v WHERE i<:1)SELECT SIGN(LEVEL-1) FROM DUAL WHERE LEVEL-1<=:1 CONNECT BY LEVEL<4UNION ALL SELECT d FROM v WHERE:1>2;

ゴルフをしていない

WITH v(a,b,c,d,i) AS 
(
  SELECT 0,1,1,4,3 FROM DUAL 
  UNION ALL 
  SELECT b,c,d,3*c-a,i+1 FROM v WHERE i<:1
)
SELECT SIGN(LEVEL-1) FROM DUAL WHERE LEVEL-1<=:1 CONNECT BY LEVEL<4
UNION ALL SELECT d FROM v WHERE:1>2;

シーケンスの最初の3つの要素を生成するためにSIGN関数を使用して(?を使用して)数バイトを得ることができました。


3

Japt、25 22 21バイト

Uò £MgXf2)+X%2*Mg°X)r

オンラインでテストしてください!

バックグラウンド

Japtでフィボナッチ数列を作成することはやや困難ですが、それを行うためのビルトインがありMgます。ただし、これはフィボナッチ数列のみを提供し、ルーカス数列は提供しません。このトリックを使用して、Lucasシーケンスをかなり簡単に実現できます。

N    F(N-1)  F(N+1)  F(N-1)+F(N+1)
0    1       1       2
1    0       1       1
2    1       2       3
3    1       3       4
4    2       5       7
5    3       8       11
6    5       13      18
7    8       21      29

ご覧のとおり、F(N-1) + F(N+1)は、L(N)forに等しいNです。ただし、奇数インデックスのルーカス数のみが必要なため、2つの式を1つにまとめることができます。

N    N-N%2  N+N%2    F(N-N%2)  F(N+N%2)*(N%2)  F(N-N%2)+F(N+N%2)*(N%2)
0    0      0        0         0               0
1    0      2        0         1               1
2    2      2        1         0               1
3    2      4        1         3               4
4    4      4        3         0               3
5    4      6        3         8               11
6    6      6        8         0               8
7    6      8        8         21              29

使い方

Uò £  MgX-1 +X%2*Mg° X)r
Uò mX{MgX-1 +X%2*Mg++X)r

             // Implicit: U = input integer
Uò mX{       // Create the inclusive range [0..U], and map each item X to:
MgXf2)+      //  Floor X to a multiple of 2, calculate this Fibonacci number, and add:
+X%2*Mg++X)  //  Calculate the (X+1)th Fibonacci number and multiply by X%2.
)r           //  Round the result. (The built-in Fibonacci function returns
             //  a decimal number on higher inputs.)

3

Mathematica、52 51バイト

If[#>2,3#0[#-2]-#0[#-4],#-If[#>1,1,0]]&/@0~Range~#&

上記のMartinと非常によく似た考えで、関数の「ベースケース」を定義するより短い方法を見つけるために時間を費やしました。多項式補間は破綻したので、ネガティブへの拡張を使用してかなり短い定義を得るためにこれに進みました。


2

Mathematica、56バイト

f@0=0
f@1=f@2=1
f@3=4
f@n_:=3f[n-2]-f[n-4];
f/@0~Range~#&

非常に簡単な実装。ヘルパー関数を定義し、すべての結果を取得するために範囲にf適用される名前のない関数に評価しfます。これは、不必要に面倒です。

ただし、名前のない単一の関数は1バイト長くなります。

Switch[#,0,0,1,1,2,1,3,4,_,3#0[#-2]-#0[#-4]]&/@0~Range~#&

2

MATL、17 18バイト

0ll4i:"y3*5$y-](x

MartinのCJam回答のほぼ直接的な翻訳。

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

0ll4       % push first four numbers: 0,1,1,4
i:         % input n and generate array [1,2,...,n]
"          % for loop. Repeat n times
  y        % copy second-top element from stack
  3*       % multiply by 3
  5$y      % copy fifth-top element from stack
  -        % subtract. This is the next number in the sequence
]          % end loop
(x         % indexing operation and delete. This gets rid of top three numbers

2

Brachylog、51バイト

:0re{:4<:[0:1:1:4]rm!.|-4=:1&I,?-2=:1&*3-I=.}w,@Sw\

これは入力として数値を受け取り、各数値をスペースで区切ってリストを標準出力に出力します。

説明

§ Main predicate

:0re{...}               § Enumerate integers between 0 and the Input, pass the integer 
                        § as input to sub-predicate 1      
         w,@Sw          § Write sub-predicate 1's output, then write a space
              \         § Backtrack (i.e. take the next integer in the enumeration)


§ Sub-predicate 1

:4<                     § If the input is less than 4
   :[0:1:1:4]rm!.       § Then return the integer in the list [0,1,1,4] at index Input

|                       § Else

-4=:1&I,                § I = sub_predicate_1(Input - 4)
        ?-2=:1&*3-I=.   § Output = sub_predicate_1(Input - 2) * 3 - I

!サブ述語1の最初のルールのカットは、バックトラック(\)したときに、インタープリターが4未満の入力に対して2番目のルールを試行する無限ループに陥らないようにするために必要です。



2

Groovy、50バイト

x={a,b=0,c=1,d=1,e=4->a<0?:[b,x(a-1,c,d,e,3*d-b)]}

これは関数xを定義します。これは、nを最初の引数として受け取り、Fibocasシーケンスの最初の4つの数値のベースケースを残りの関数のデフォルト引数として持ちます。

ここはnです。b、c、d、およびeは、シーケンスの次の4つの要素です。

nをデクリメントし、nがゼロより小さくなるまで再帰します。再帰すると、現在のシーケンスの最初の要素を最終的な戻り値に追加します。シーケンスの次の4つの要素の新しい値は再帰呼び出しに与えられます。最後の3つの要素は最初の3つにシフトされ、3 * dbを使用して前の2つの要素から新しい4番目の要素が生成されます。

groovyは複数の値をリストに詰め込むことで複数の値を返すことができるため、リストの入れ子で新しい値を区切ります。したがって、各呼び出しは現在の最初の要素と再帰の結果を返します。これは独自のリストになります。



1

パイロン、19

これは、Martinのアプローチのかなり直接的な翻訳です。

0114{@-4@-33*-,i}=4

使い方:

0114    # Push 0, 1, 1, 4 to the stack.
{       # Start a for loop.
 @-4    # Get the stack element at index -4
 @-3    # Get the stack element at index -3
 3      # Push 3 to the stack.
 *      # Multiply the top two elements of the stack.
 -      # Subtract the top two elements of the stack.
  ,     # Switch to loop iterations.
 i      # Get command line args.
}       # End for loop.
=4      # Discard the top 4 elements of the stack.

1

DUP、32バイト

[a:0 1$4[a;1-$a:][1ø3*4ø-]#%%]

Try it here!

スタックに数字のシーケンスを残す匿名ラムダ。使用法:

8[a:0 1$4[a;1-$a:][1ø3*4ø-]#%%]!

説明

[                              {start lambda}
 a:                            {save input number to a}
   0 1$4                       {base cases to get us started}
        [       ][       ]#    {while loop}
         a;1-$a:               {a--, check if a>0}
                  1ø3*4ø-      {3*stack[n-2]-stack[n-4]}

                           %%  {discard top 2 stack items}
                             ] {end lambda}

1

Python 2、71バイト

def a(n,x=0,y=1,z=2,w=1,p=0):
 if~n:print[x,z][p];a(n-1,y,x+y,w,z+w,~p)

これは間違いなく長すぎるようです。しかし、ビットnot演算子を2回使用できるようになったことを嬉しく思いました。パリティの一種として前後に反転し、にn達し-1たときに再帰を終了します。

変数pは常に0またはのいずれか-1になるため、エントリ間0または-1リスト内で交互に使用されます。(-1Pythonリストのエントリを選択すると、最後の要素が選択されます。)


1

C ++テンプレートメタプログラミング、130バイト

template<int X>struct L{enum{v=3*L<X-2>::v-L<X-4>::v};};
#define D(X,A) template<>struct L<X>{enum{v=A};};
D(0,0)D(1,1)D(2,1)D(3,4)

再帰的な定義は、C ++ TMPをどうにかして泣かせます、使用法:

L<x>::v

xことA(x)が好き。

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