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


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/FibachNumber.html
Ніл

1
Хоча код гольфу не повинен виправдовувати запит (я думаю), це здається дивною операцією; згідно з ним, оскільки 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 є єдиним аргументом нашої монадичної програми.

¡це швидкий , що означає, що він споживає деякі посилання зліва і перетворює їх у швидке посилання . ¡зокрема споживає одну або дві ланки.

  • <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) , який обчислює бажаний вихід.


Ах, наскільки корисно це для викликів Фібоначчі. Чи було цілеспрямованим мати ¡роботу на зразок філоса з діадами?
Ерік Аутгольфер

Oooh - %1+¡лінійна інтерполяція між n × F (n) при n і n × F (n-1) + F (n) при n-ε , і посилюється між n-ε і n .
Джонатан Аллан

@EriktheOutgolfer Ну, більш-менш. Оскільки у Jelly немає змінних, ви втратите доступ до попередніх членів послідовності в іншому випадку, тому має сенс реалізувати це так.
Денніс

@JonathanAllan Я не впевнений, що розумію. Що %1+¡робити?
Денніс

@Dennis erm, мається на увазі , добре \ _o_ / ... але це, як видається, стосується експериментів: D
Джонатан Аллан

5

Математика, 32 байти

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

Чиста функція, яка приймає як вхідне невід’ємне дійсне число і повертає дійсне число. Якщо 1~Max~#його замінити 1, це було б стандартним рекурсивним визначенням 0-індексованих чисел Фібоначчі для цілих аргументів. Але 1~Max~#це правильна кусочно-лінійна функція для реальних входів між 0 і 2, а рекурсія піклується про інше. (Фактичний факт: зміна цього на 1-індексовані числа Фібоначчі може бути досягнуто просто зміною Maxна a 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>

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


Це розумно. Я думав, що це не працює.
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, 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 .


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)}

Спробуй це

Розширено:

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 рішення


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.