卢卡斯-纳奇数


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)=10000

一个密切相关的序列是卢卡斯数 L(m)

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

这些由L(m) = L(m-1) + L(m-2)L(0)=2和的递归函数形成L(1)=10000

我们可以根据偶数/奇数索引在两个序列之间进行交替,并使用
A(x) = F(x)if x mod 2 = 0A(x) = L(x)else 的构造。例如,A(4)等于F(4)以来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)=4005

挑战

给定输入n,输出n+1直至和包括A(n)如上所述的数字序列。最小字节(或等效字节,例如对于LabVIEW,由Meta分别确定)获胜。

输入项

单个非负整数 n

输出量

对应于Lucas-nacci数字从A(0)到的子序列的数字列表A(n)。如上所述,列表必须按顺序排列。

规则

  • 适用标准代码高尔夫球规则和漏洞限制
  • 标准输入/输出规则适用。
  • 输入数字可以采用任何合适的格式:一进制或十进制,从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 '02

@corsiKa当然可以。
AdmBorkBork '16

Answers:


9

果冻,12个字节

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

在线尝试!

背景

通过定义F(-1)= 1和L(-1)= -1,我们可以将F和L扩展为-1。这与递归函数一致。

我们的程序开始于

-1  1
 0  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.

С偷看左边的两个链接:2U+¥。由于最左边的一个是尼拉德,因此它不能成为循环的主体。因此,U+¥用作正文,并从输入中读取数字。由于没有命令行参数,因此将从STDIN中读取该数字。


2
我的印象是,您从事此类工作(在果冻中打高尔夫球)为生。这让我感到恐惧。
Draco18s

24
如果有人想出了如何打高尔夫球(代码)为生,请在聊天中对我进行ping操作。问一个朋友……
Martin Ender

2
因此,基本上,您只是在计算两个序列,但是在每个步骤都进行了反转,从而可以在序列之间进行有效切换。
尼尔

1
@Neil是的,完全是。这样可以避免以后交织序列,因为交织序列会稍长一些。
丹尼斯

6

CJam,21个 20字节

感谢Sp3000节省了1个字节。

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 Dennis


5
@CJDennis有人说他是有史以来最伟大的Python高尔夫球手。有人说他住在一个山顶的僻静小屋里,这个小屋是用最少的原木建造的。有人说他是我们脑海中的声音,当我们发布可以进一步推广的解决方案时,这让我们很烦。但是我们大多数人只是说他是Martin所关联的用户。
Mego 2016年

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
我想出的最清晰的lambda是{( (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

Haskell中,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对于奇数输入(Lucas系列)返回2或对于偶数(Fibonacci系列)返回0。 lucasNacci i给出第i个Lucas-nacci数。 firstN n映射到列表。

Boomerang保存的一个字节。


1
我认为您可以通过2*mod i 2移入l再获得一个字节,然后删除括号。像这样:l a=2*mod a 2:scanl(+)1(l a)f n=[l i!!i|i<-[0..n]]
basile-henry

@Boomerang是的,可以。谢谢
Michael Klein

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 1s。
  • 1? $`¶ -为从0到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 -循环:计算F(n + 1)= F(n)+ F(n-1),同时还有1s。
  •  f*   -从每行的末尾删除F(n + 1)。
  • fs 替换回1s。如果不需要这样做,我们可以使用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;

通过使用(滥用?)SIGN函数生成了序列的前3个元素,我设法获得了一些字节。


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)所有N。但是,由于我们只需要在奇数索引上使用卢卡斯数,就可以将两个公式组合为一个:

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~#&

与上面的马丁非常相似,我花了一些时间试图找到一种为函数定义“基本案例”的较短方法。多项式插值是一个失败,所以我为此做,使用扩展为负数来产生一个相当短的定义。


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一个范围以获取所有结果。这感觉不必要地麻烦。

单个未命名函数似乎长了一个字节:

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

马丁的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\

这将一个数字作为输入并打印到STDOUT列表,每个数字之间用空格隔开。

说明

§ 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

Mathematica,41个字节

LinearRecurrence[{0,3,0,-1},{0,1,1,4},#]&

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序列中前四个数字的基数作为该函数其余部分的默认参数。

这里是n。b,c,d和e是序列中的后四个元素。

它递减n并递归直到n小于零-递归时,它将当前序列中的第一个元素加到最终返回值上。序列中接下来的四个元素的新值将提供给递归调用-将最后三个元素移至前三个元素,并使用3 * db从先前的两个元素中生成一个新的第四个元素。

它用列表嵌套来界定新值,因为groovy可以通过将它们填充到列表中来返回多个值-因此每个调用都将返回当前的第一个元素和递归结果,这将是它自己的列表。



1

定向塔,19

这是马丁方法的直接翻译。

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!

匿名lambda,它在堆栈上保留一系列数字。用法:

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符...两次。一旦作为一种奇偶翻盖来回,而一旦终止递归时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)你喜欢。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.