Линейная интерполяция последовательности Фибоначчи

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- м и 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
Операция, которую вы здесь делаете, называется «линейная интерполяция». (Вы не возражаете, если я изменил название поста, чтобы отразить это?) Кажется, у него есть свойство Фибоначчи, которое f (n-2) + f (n-1) = f (n), так что я думаю, это разумное обобщение последовательности Фибоначчи. (Я не уверен, есть ли какое-либо стандартное обобщение.)
@ ais523, если вы думаете, что это улучшит вопрос, тогда да, вы можете изменить название поста.
Даниэль
Я думаю, что в будущем вопрос будет легче найти, если кто-то спросит что-то подобное, а также прояснит, о чем идет речь, скажем, в «Связанном» списке. Таким образом, это поможет улучшить вопрос, помогая доставить ответчиков в нужное место.
2
@ais Похоже, есть обобщение формулы Бине: mathworld.wolfram.com/FibonacciNumber.html
Нил,
1
Хотя Code Golf не должен оправдывать запрос (я думаю), это кажется странной операцией; в соответствии с этим, так как F_0 = 0и F_2 = 1мы должны иметь F_1 = (1/2)(F_0 + F_2) = 1/2.
LSpice

Ответы:

7

Желе , 5 байт

_Ḟ1+¡

Это итеративное решение без встроенных модулей. Он использует ту же индексацию, что и спецификация задачи.

Попробуйте онлайн!

Фон

Пусть f - функция, определенная в спецификации вызова, а F - функция Фибоначчи, определенная как обычно (т. Е. С F (0) = 0 ). Для неотрицательного целого числа n имеем f (n) = F (n + 1) . Когда 0 ≤ x <1 , спецификация вызова определяет f (n + x) как f (n) + (f (n + 1) - f (n)) x .

Очевидно, что это влияет только базовые случаи, но не рекурсивная формула, то есть F (п) = е (п - 1) + F (п - 2) имеет место , как это было бы для F . Это означает, что мы можем упростить определение для нецелочисленных аргументов до более простого f (n) = f (n) + f (n - 1) x .

Как отметили другие в своих ответах, рекурсивные отношения также справедливы для нецелых аргументов. Это легко проверить, так как

доказательство

Поскольку f (0) = f (1) = 1 , f постоянна в интервале [0, 1] и f (0 + x) = 1 для всех x . Кроме того, f (-1) = F (0) = 0 , поэтому f (-1 + x) = f (-1) + (f (0) - f (-1)) x = 0 + 1x = x . Эти базовые случаи охватывают [-1, 1) , поэтому вместе с рекурсивной формулой они завершают определение f .

Как это устроено

Как и раньше, пусть n + x будет единственным аргументом нашей монадической программы.

¡это быстро , а это означает , что он потребляет несколько ссылок на его левый и превращает их в QuickLink . ¡в частности потребляет одну или две ссылки.

  • <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) , который вычисляет желаемый результат.

Деннис
источник
Ааа, насколько это полезно для вызовов Фибоначчи. Было ли целесообразно ¡работать с диадами, как Фибоначчи?
Эрик Outgolfer
Ооо - %1+¡: линейная интерполяция между n × F (n) в n и n × F (n-1) + F (n) в n-ε , и шаг между n-ε и n .
Джонатан Аллан
@EriktheOutgolfer Ну, более или менее. Поскольку у Jelly нет переменных, в противном случае вы потеряете доступ к предыдущим элементам последовательности, поэтому имеет смысл реализовать это следующим образом.
Деннис
@JonathanAllan Я не уверен, что понимаю. Что %1+¡должен делать?
Деннис
@ Деннис, ну, значит , хорошо \ _o_ / ... но это то, что он делает с экспериментами: D
Джонатан Аллан
5

Mathematica, 32 байта

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

Чистая функция, принимающая неотрицательное действительное число в качестве входных данных и возвращающая действительное число. Если 1~Max~#их заменить на 1, это будет стандартное рекурсивное определение 0-индексированных чисел Фибоначчи для целочисленных аргументов. Но 1~Max~#это правильная кусочно-линейная функция для реальных входов от 0 до 2, и рекурсия позаботится обо всем остальном. (Пустяки факт: изменение этого к 1-индексированных чисел Фибоначчи может быть достигнуто лишь путем изменения Maxк Min!)

Самое короткое, что я мог получить со встроенным, это 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>

Тривиальная модификация рекурсивного определения последовательности Фибоначчи с нулевым индексом. Может давать небольшие ошибки округления для некоторых входных данных.

ETHproductions
источник
Это умно. Я думал, что это не сработало.
Утренняя монахиня
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, 137 124 119 113 102 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 . Выходная ячейка - А1 .

qoou
источник
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$

При этом используется та же индексация, что и в спецификации задачи.

Попробуйте онлайн!

Фон

Согласно спецификации, мы имеем F (n + x) = F (n) + (F (n + 1) - F (n)) x , для натурального n и 0 ≤ x <1 . Поскольку 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)}

Попытайся

Expanded:

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
}

Это было вдохновлено другими решениями Python и Javascript

Брэд Гилберт b2gills
источник