Linear interpolation of the Fibonacci sequence
Jelly, 5 bytes
_Ḟ1+¡
This is an iterative solution without built-ins. It uses the same indexing as the challenge spec.
Try it online!
Background
Let f be the function defined in the challenge spec and F the Fibonacci function defined as usual (i.e., with F(0) = 0). For a non-negative integer n, we have f(n) = F(n + 1). When 0 ≤ x < 1, the challenge spec defines f(n + x) as f(n) + (f(n + 1) - f(n))x.
Clearly, this just affects the base cases, but not the recursive formula, i.e., f(n) = f(n - 1) + f(n - 2) holds as it would for F. This means we can simplify the definition for non-integer arguments to the easier f(n) = f(n) + f(n - 1)x.
As others have noted in their answers, the recursive relationship also holds for non-integer arguments. This is easily verifiable, as
Since f(0) = f(1) = 1, f in constant in the interval [0, 1] and f(0 + x) = 1 for all x. Furthermore, f(-1) = F(0) = 0, so f(-1 + x) = f(-1) + (f(0) - f(-1))x = 0 + 1x = x. These base cases cover in [-1, 1), so together with the recursive formula, they complete the definition of f.
How it works
As before, let n + x be the only argument of our monadic program.
¡
is a quick, meaning that it consumes some links to its left and turns them into a quicklink. ¡
in particular consumes either one or two links.
<F:monad|dyad><N:any>
calls the link N, returning r, and executes F a total of r times.<nilad|missing><F:monad|dyad>
sets r to the last command-line argument (or an input from STDIN in their absence) and executes F a total of r times.
Since 1
is a nilad (a link without arguments), the second case applies, and +¡
will execute +
n times (a non-integer argument is rounded down). After each call to +
, the left argument of the quicklink is replaced with the return value, and the right argument with the previous value of the left argument.
As for the entire program, Ḟ
floors the input, yielding n; then _
subtract the result from the input, yielding **x, which becomes the return value.
1+¡
then calls +¡
– as described before – with left argument 1 = f(0 + x) and right argument x = f(-1 + x), which computes the desired output.
Mathematica, 32 bytes
If[#<2,1~Max~#,#0[#-1]+#0[#-2]]&
Pure function taking a nonnegative real number as input and returning a real number. If 1~Max~#
were replaced by 1
, this would be the standard recursive definition of the 0-indexed Fibonacci numbers for integer arguments. But 1~Max~#
is the correct piecewise linear function for real inputs between 0 and 2, and the recursion takes care of the rest. (Trivia fact: changing this to the 1-indexed Fibonacci numbers can be accomplished simply by changing the Max
to a Min
!)
The shortest I could get with the builtin is the 37-byte (b=Fibonacci)[i=Floor@#](#-i)+b[i+1]&
.
JavaScript (ES6), 30 bytes
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>
Trivial modification of the zero-indexed recursive Fibonacci sequence definition. May give slight rounding errors for some inputs.