Negative Fibonacci Numbers

28

1

You probably all know the fibonacci sequence:

fibonacci(n)=fibonacci(n-1)+fibonacci(n-2)
fibonacci(0)=0
fibonacci(1)=1

Your task is as simple as it could be:

  • Given integer N compute fibonacci(n)

but here is the twist:

  • Also do negative N

Wait. What?

fibonacci(1)=fibonacci(0)+fibonacci(-1)

so

fibonacci(-1)=1

and

fibonacci(-2)=fibonacci(0)-fibonacci(1)=-1

and so on...

  • This is a so shortest programm in bytes win.
  • You may submit a function or a full programm
  • N is in [-100,100]

Testcase(s) in CSV:

-9;-8;-7;-6;-5;-4;-3;-2;-1;0;1;2;3;4;5;6;7;8
34;-21;13;-8;5;-3;2;-1;1;0;1;1;2;3;5;8;13;21

Hint:

n<0 and n&1==0:

fibonacci(n)=fibonacci(abs(n))*-1

Roman Gräf

Posted 2016-12-31T10:43:52.013

Reputation: 2 915

No. Mine wants you to support negative numbers too. – Roman Gräf – 2016-12-31T10:52:17.587

7I think this is not a dupe. Of the answers on the first page of the existing Fibonacci challenge, only 1 can handle negatives, and all the rest would need to be significantly changed to go backwards too. – xnor – 2016-12-31T11:01:12.930

Added some. Feel free to add more. @Flip – Roman Gräf – 2016-12-31T12:02:31.443

1

Read this meta post about formatting test cases: try to avoid fancy tables

– FlipTack – 2016-12-31T12:08:29.570

and by CSV you mean SSV (semicolon separated values)? – NH. – 2016-12-31T13:55:40.350

@NH. "European CSV" https://en.wikipedia.org/wiki/Comma-separated_values#Example

– Slai – 2017-01-01T05:54:58.650

Answers

22

Mathematica, 9 bytes

Fibonacci

Yes, this built-in function supports negative numbers.

alephalpha

Posted 2016-12-31T10:43:52.013

Reputation: 23 988

2This is almost word-for-word the answer I was coming to post :D – Greg Martin – 2016-12-31T20:13:27.283

17

Octave, 20 bytes

 @(n)([1,1;1,0]^n)(2)

Try it online!

Explanation

This makes use of the fact that the fibonacci sequence f(n) can be written as (this should be a matrix vector notation):

Recursively:

[f(n+1)]  = [1  1] * [f(n)  ]
[f(n)  ]    [1  0]   [f(n-1)]

Explicitly:

[f(n+1)]  = [1  1] ^n * [1]
[f(n)  ]    [1  0]      [0]

This means that the top right entry of this matrix to the power of n is the value f(n) we're looking for. Obviously we can also invert this matrix as it has full rank, and the relationship still describes the same recurrence relation. That means it also works for negative inputs.

flawr

Posted 2016-12-31T10:43:52.013

Reputation: 40 560

1(How) Does this also work for negative input? – Roman Gräf – 2016-12-31T10:57:01.330

yes, explanation coming... – flawr – 2016-12-31T10:57:40.553

is ans(-6) meant to be positive? – FlipTack – 2016-12-31T11:02:04.067

@FlipTack Sorry, it might have been because of the index shift. I used 1-based, while the question used 0-based, I fixed it now. – flawr – 2016-12-31T11:09:08.983

13

Maxima, 3 bytes

 fib

supports positive and negative numbers.

Try it (paste) on CESGA - Maxima on line

rahnema1

Posted 2016-12-31T10:43:52.013

Reputation: 5 435

Can you add a link to the language? – Pavel – 2017-01-01T00:38:50.917

Of course added a link to an online calculator! – rahnema1 – 2017-01-01T03:49:15.483

Also works on WolframAlpha – Thunda – 2017-03-24T06:58:28.347

11

Python, 43 bytes

g=5**.5/2+.5
lambda n:(g**n-(1-g)**n)/5**.5

A direct formula with the golden ratio g. With f the above function:

for n in range(-10,11):print f(n) 

-55.0
34.0
-21.0
13.0
-8.0
5.0
-3.0
2.0
-1.0
1.0
0.0
1.0
1.0
2.0
3.0
5.0
8.0
13.0
21.0
34.0
55.0

Same length alt, only aliasing the square root of 5:

a=5**.5
lambda n:((a+1)**n-(1-a)**n)/a/2**n

I didn't see a way to make a recursive function that could compete with these. A mildly-golfed attempt for 57 bytes:

f=lambda n:n<0and(-1)**n*f(-n)or n>1and f(n-1)+f(n-2)or n

For comparison, an iterative method (60 bytes in Python 2):

n=input()
a,b=0,1;exec"a,b=b,a+b;"*n+"a,b=b-a,a;"*-n
print a

Or, for 58 bytes:

n=input()
a,b=0,1;exec"a,b=b,a+cmp(n,0)*b;"*abs(n)
print a

xnor

Posted 2016-12-31T10:43:52.013

Reputation: 115 687

10

JavaScript (ES6), 42 bytes

f=n=>n<2?n<0?f(n+2)-f(n+1):n:f(n-2)+f(n-1)

Test

f=n=>n<2?n<0?f(n+2)-f(n+1):n:f(n-2)+f(n-1)

for(i = -9; i < 9; i++) {
  console.log(i, f(i))
}

Arnauld

Posted 2016-12-31T10:43:52.013

Reputation: 111 334

I really like your function. I had a suggestion here, but I overlooked a -, so it wouldn't work... – Luke – 2016-12-31T13:43:02.700

5

MATL, 11 9 bytes

I'm happy about the [3,2], which surely could be golfed, if anyone knows a way please let me know=) (It would also work with [1,3].) Thanks @LuisMendo for -2 bytes=)

IHhBiY^2)

This is using the same approach as the Octave annswer. But to generate the matrix

[1,1]
[1,0]

we just conver the number 3 and 2 from decimal to binary (i.e. 11 and 10).

Try it online!

flawr

Posted 2016-12-31T10:43:52.013

Reputation: 40 560

5

JavaScript (ES7) 37 bytes

Uses Binet's Formula.

n=>((1+(a=5**.5))**n-(1-a)**n)/a/2**n

This outputs the nth Fibonacci number +- 0.0000000000000005.

Luke

Posted 2016-12-31T10:43:52.013

Reputation: 4 675

** requires ES7. – Neil – 2016-12-31T15:39:14.037

Oh, thought it was part of ES6, but you're right. Changed it. I also used another version of Binet's Formula for a 1B save. – Luke – 2016-12-31T17:30:15.473

Now that I think about it, just using 1-p instead of -1/p should have worked for the same saving. – Neil – 2016-12-31T17:41:54.583

3

Jolf, 2 bytes

mL

Try it here!

The fibonacci builtin, implemented using the phi formula.

Conor O'Brien

Posted 2016-12-31T10:43:52.013

Reputation: 36 228

Uncaught SyntaxError: Unexpected token | at new Function (<anonymous>) at p (math.min.js:27) at Object (math.min.js:27) at typed (eval at p (math.min.js:27), <anonymous>:36:14) at Object.n [as factory] (math.min.js:45) at t (math.min.js:27) at f (math.min.js:27) at Object.get [as median] (math.min.js:27) at clone (rawgit.com/ConorOBrien-Foxx/Jolf/master/src/jolf.js:902) at rawgit.com/ConorOBrien-Foxx/Jolf/master/src/jolf.js:2128 (Latest Google Chrome, version 55.0.2883.87m) – Ismael Miguel – 2017-01-02T00:05:28.250

@IsmaelMiguel This should only work on firefox – Conor O'Brien – 2017-01-02T01:08:30.040

I had no idea, it isn't anywhere – Ismael Miguel – 2017-01-02T01:17:25.430

2

Haskell, 51 bytes

s=0:scanl(+)1s;f z|even z,z<0= -f(-z);f z=s!!abs z

Roman Czyborra

Posted 2016-12-31T10:43:52.013

Reputation: 604

1Multiple tests within a guard can be combined with , instead of &&: even z,z<0. – nimi – 2017-01-02T23:54:45.580

1

Lithp, 88 bytes

#N::((if(< N 2)((if(< N 0)((-(f(+ N 2))(f(+ N 1))))((+ N))))((+(f(- N 2))(f(- N 1))))))

My look at all those parentheses.

Try it online!

Not very small really. There's currently a parsing bug that requires one to use (get N) or (+ N) instead of simply N. I chose the smaller one. However I don't think there's anything that can be done further to golf this.

Andrakis

Posted 2016-12-31T10:43:52.013

Reputation: 361

1

PowerShell, 112 Bytes

function f($n){$o=('-','+')[$n-lt0];&(({$a,$b=(2,1|%{f("$n$o$_"|iex)});"$a- $o$b"|iex},{$n*$n})[$n-in(-1..1)])}

Demo Call:

-9..9 | %{"{0,2}`t=> {1,3}" -f $_,(f($_))} 

Output of Demo:

-9  =>  34
-8  => -21
-7  =>  13
-6  =>  -8
-5  =>   5
-4  =>  -3
-3  =>   2
-2  =>  -1
-1  =>   1
 0  =>   0
 1  =>   1
 2  =>   1
 3  =>   2
 4  =>   3
 5  =>   5
 6  =>   8
 7  =>  13
 8  =>  21
 9  =>  34

JohnLBevan

Posted 2016-12-31T10:43:52.013

Reputation: 151