斐波那契数列的线性插值


20

您的任务是找到第n 斐波那契数,但n不一定是整数。

索引为0的斐波那契数列如下:

0, 1, 2, 3, 4, 5,  6,  7, ...

1, 1, 2, 3, 5, 8, 13, 21, ...

但是,如果我们想要第2 .4 数字怎么办?

2.4 数量是0.4倍3之间的差RD和2 斐波那契数加上2 斐波那契数。因此,2.4 斐波那契数是2 + 0.4 * (3 – 2) = 2.4

同样,第6.35 斐波那契数为13 + 0.35 * (21 – 13) = 15.8

您的任务是找到第n 斐波那契数,以使n大于或等于0。

您可以执行零索引或一索引,只需说出您正在使用的索引。

这是,因此以字节为单位的最短代码胜出!

其他示例:

0        1
4.5    6.5
0.7      1
7       21

2
您在此处执行的操作称为“线性插值”。(您介意我是否更改帖子标题以反映这一点?)它似乎具有Fibonacci属性,即f(n-2)+ f(n-1)= f(n),所以我想这是斐波那契数列的合理概括。(我不确定是否有任何标准概括。)

@ ais523,如果您认为这可以改善问题,那么可以,您可以更改帖子标题。
丹尼尔(Daniel)

我认为,如果有人提出类似的问题,将来可以更轻松地找到问题,并且可以使问题变得更明确,例如“相关”列表。因此,通过帮助将答题者带到正确的位置,它将使问题变得更好。

2
@ais似乎有Binet公式的一般化:mathworld.wolfram.com/FibonacciNumber.html
Neil

1
尽管代码高尔夫不必证明请求合理(我想),但这似乎很奇怪。根据它,既然F_0 = 0F_2 = 1,我们应该有F_1 = (1/2)(F_0 + F_2) = 1/2
LSpice

Answers:


7

果冻,5个字节

_Ḟ1+¡

这是一个没有内置的迭代解决方案。它使用与挑战规范相同的索引。

在线尝试!

背景

f为挑战规范中定义的函数,而F为通常定义的Fibonacci函数(即F(0)= 0)。对于非负整数n,我们有f(n)= F(n + 1)。当0≤x <1时,质询规范将f(n + x)定义为f(n)+(f(n + 1)-f(n))x

显然,这仅影响基本情况,但不影响递归公式,即f(n)= f(n-1)+ f(n-2)F一样成立。这意味着我们可以将非整数参数的定义简化为更容易的f(n)= f(n)+ f(n-1)x

正如其他人在回答中指出的那样,递归关系也适用于非整数参数。这很容易验证,因为

证明

由于f(0)= f(1)= 1,因此对于所有xf均[0,1]区间内不变,并且f(0 + x)= 1。此外,f(-1)= F(0)= 0,因此f(-1 + x)= f(-1)+(f(0)-f(-1))x = 0 + 1x = x。这些基本情况涵盖在[-1,1)中,因此它们与递归公式一起完成了f的定义。

怎么运行的

和以前一样,让n + x为单子程序的唯一参数。

¡是一种快速的,这意味着它会占用一些链接到它的左侧,把它们变成一个快速链接¡特别是消耗一个或两个链接。

  • <F:monad|dyad><N:any>调用链接N,返回r,并执行F总共r次。

  • <nilad|missing><F:monad|dyad>r设置为最后一个命令行参数(或缺少STDIN的输入),并执行F总共r次。

由于1是nilad(没有参数的链接),因此第二种情况适用,并且将执行+ n次(将非整数参数舍入)。每次调用后+,快速链接的左参数将被返回值替换,右参数将被左参数的先前值替换。

对于整个程序,对输入进行底数运算,得到n;然后_从输入中减去结果,得出** x,它成为返回值。

1+¡然后,如前所述,使用左参数1 = f(0 + x)和右参数x = f(-1 + x)调用,以计算所需的输出。


啊,对斐波那契挑战很有用。¡像斐波那契这样的工作有目的性吗?
Erik the Outgolfer '17

哦- %1+¡:之间的线性插值的n×F(n)的ÑN×F(N-1)+ F(n)的正ε之间,并且加强正εÑ
乔纳森·艾伦

@EriktheOutgolfer好吧,或多或少。由于Jelly没有变量,否则您将失去对先前序列成员的访问权,因此像这样实现它是有意义的。
丹尼斯

@JonathanAllan我不确定我是否理解。什么是%1+¡应该做的?
丹尼斯

@Dennis erm,意思是,\ _ o_ / ... ...但这似乎与实验有关:D
Jonathan Allan

5

Mathematica,32个字节

If[#<2,1~Max~#,#0[#-1]+#0[#-2]]&

将非负实数作为输入并返回实数的纯函数。如果1~Max~#被替换1,这将是整数参数的0索引斐波那契数的标准递归定义。但是1~Max~#对于0到2之间的实数输入,正确的分段线性函数是正确的,递归会处理其余部分。(琐事事实:将其更改为1索引的斐波那契数可以简单地通过将其更改MaxMin!来完成。)

我可以用内建函数得到的最短时间是37字节(b=Fibonacci)[i=Floor@#](#-i)+b[i+1]&



3

JavaScript(ES6),30个字节

f=x=>x<1?1:x<2?x:f(x-1)+f(x-2)
<input type=number value=2.4 oninput="O.value=f(value)"> <input id=O value=2.4 disabled>

零索引递归斐波那契序列定义的简单修改。某些输入可能会产生一些舍入误差。


这很聪明。我以为那没用。
Leaky Nun

1

果冻17 12字节

’Ñ+Ñ
’»0‘ÇỊ?

在线尝试!

非内置解决方案。

说明

辅助功能 1Ŀ

’Ñ+Ñ
 Ñ    Call the main program on
’       {the input} - 1;
   Ñ  Call the main program on {the input};
  +   Add those results{and return the result}

主程序

’»0‘ÇỊ?
’        Subtract 1
 »0      but replace negative results with 0
     Ị?  If the result is less than or equal to 1
   ‘     Return the result plus 1
    Ç    else return the result

因此,在0到1范围内的输入将饱和减为0,因此我们加1得到F(0)= F(1)= 1。1到2范围内的输入将返回自身。这些基本情况足以进行典型的斐波那契递归并从此处计算其他值。


1

Excel,137124119119102 97字节

非递归/迭代方法。(直接计算第n个项)这使用一个索引方法。添加+1=TRUNC(B1)会将其更改为零索引。

=A7+(A8-A7)*MOD(B1,1)
=5^.5
=(1+A2)/2
=TRUNC(B1)
=A4+1
=-1/A3
=(A3^A4-A6^A4)/A2
=(A3^A5-A6^A5)/A2

该代码段旨在放置在单元格A1中

输入单元格为B1。输出单元为A1


1

JavaScript(ES6),67 64字节

舍入有一些问题

n=>(i=(g=(z,x=1,y=0)=>z?g(--z,x+y,x):y)(++n|0))+n%1*(g(++n|0)-i)

试试吧

f=
n=>(i=(g=(z,x=1,y=0)=>z?g(--z,x+y,x):y)(++n|0))+n%1*(g(++n|0)-i)
console.log(f(2.4))
console.log(f(6.35))
console.log(f(42.42))



0

果冻13 9字节

,‘ḞÆḞḅ%1$

这使用与挑战规范相同的索引。

在线尝试!

背景

根据规范,对于自然n0≤x <1,我们有F(n + x)= F(n)+(F(n + 1)-F(n))x。由于F(n + 1)= F(n)+ F(n-1),因此可以将其重写为F(n + x)= F(n)+ F(n-1)x

此外,挑战规范中使用的索引定义了函数f(n)= F(n + 1)(其中F是通常的斐波那契函数,即F(0)= 0),因此我们得到公式f(n + x)= F(n + 1)+ F(n)x

怎么运行的

,‘ḞÆḞḅ%1$  Main link. Argument: n + x

 ‘         Increment; yield n + 1 + x.
,          Pair; yield [n + x, n + 1 + x].
  Ḟ        Floor; yield [n, n + 1].
   ÆḞ      Fibonacci; yield [F(n), F(n + 1)].
      %1$  Modulus 1; yield (n + x) % 1 = x.
     ḅ     Unbase; yield F(n)x + F(n + 1).

0

Perl 6  48  38个字节

48

{$/=(1,1,*+*...*)[$_,$_+1];$0+($_-.Int)*($1-$0)}

试试吧

38

sub f(\n){3>n??max 1,n!!f(n-1)+f(n-2)}

试试吧

展开:

48

{
  $/ =          # store here so we can use $0 and $1
  (
    1,1,*+*...* # Fibonacci sequence
  )[
    $_,         # get the value by using floor of the input
    $_ + 1      # and get the next value
  ];

    $0            # the first value from above
  +
    ( $_ - .Int ) # the fractional part of the input
  *
    ( $1 - $0 )   # the difference between the two values in the sequence
}

$0并且$1是短期的$/[0]$/[1]

38

sub f (\n) {
    3 > n           # if n is below 3
  ??
    max 1, n        # return it if it is above 1, or return 1
                    # if it was below 1, the answer would be 1
                    # the result for numbers between 1 and 3
                    # would be the same as the input anyway
  !!
    f(n-1) + f(n-2) # the recursive way to get a fibonacci number
}

这受到其他PythonJavascript解决方案的启发


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.