Fibonacci Fibonacci sequence, very simple, is a recursive, learn any programming language may do this.

Recently playing Python, after a cursory look at learning python and core python, I stumbled upon a post on the web. The evolution of Python programmers is interesting. So I intend to imitate an article, that post used more than 10 ways to complete a factorial function, I will write a Fibonacci function in nine different styles here.

Requirements are simple, input n, output nth Fibonacci number, n is a positive integer

Here are nine different types of styles:

1) The Python programmer who wrote the program for the first time:

def fib (n): return nth Fibonacci number

Description

The person who wrote the program for the first time often follows the syntax of the human language rather than the syntax of the programming language, and takes me to a programmer who is very hard to write, he wrote the first procedure to judge a leap year, which is written directly: if year is a leap year, the output year is a leap year, otherwise year is not a leap year.

2) C programmers who have just learned python soon:

def fib (n): #{if n<=2: return 1; else: return fib (n-1) +fib (n-2); #}

Description

When I first approached Python, I was not fit to divide the blocks in such a way that they were indented and not curly braces, and there was no terminator after each statement, so the first thing to do after writing a Python function was to add the missing colon while commenting the curly braces.

3) Lazy Python programmer:

def fib (n): return 1 and n<=2 or fib (n-1) +fib (n-2)

Description

After looking at learning Python, did you know that Python has no ternary operator? , however, given that the bool value in Python is special (a bit like C, nonzero is true, non-null is true), and the logical statement of Python also supports short-circuit evaluation (short-circuit Evaluation), this can write a copy? Statement comes out.

4) More Lazy Python programmers:

Fib=lambda N:1 If n<=2 else fib (n-1) +fib (n-2)

Description

The Lambda keyword I used in C # and scheme, the lambda inside Python is simpler than C # and very much like the usage in scheme, so it quickly adapts. This is often used when declaring small functions with a python shell.

5) Python programmer who has just finished learning the data structure:

def fib (n): x,y=0,1 while (n): x,y,n=y,x+y,n-1 return x

Description

The previous Fibonacci function is the realization of the tree recursion, even if it is to learn a little bit of algorithm should know the inefficiency of this recursion. In this case, the change from tree-shaped recursion to corresponding iteration can improve the efficiency considerably.

The tuple assignment feature of Python is one of my favorite things, which can simplify the code a lot. For example, before the tmp=a;a=b;b=tmp, can be directly with a sentence a,b=b,a realization, both concise and clear.

6) Python programmer who is working on the SICP course:

def fib (n): def fib_iter (n,x,y): if N==0:return x else:return fib_iter (n-1,y,x+y) return Fib_iter (N, 0,1)

Description

Here I use the very common tail recursion (tail-recursion) notation in the scheme language. There is no iteration in scheme, but the iteration can be simulated with invariants and tails to achieve the same effect. But I'm not sure if Python has any corresponding optimizations for tail recursion, check back.

PS: See SICP classmate, one eye can see, this program is actually SICP first chapter of an example.

7) A clever Python programmer:

Fib=lambda N,x=0,y=1:x if not n else F (n-1,y,x+y)

Description

The basic logic, like the example above, is the tail-recursive notation. The main difference is that the default parameters and ternary operators provided by Python are used to simplify the code to a single line. As for the default parameters, the students who have learned C + + know this thing, as for c#4.0 also introduced this stuff.

8) A Python programmer who has just completed a linear algebra:

def fib (N): Def M1 (A, B): m=[[],[]] m[0].append (a[0][0]*b[0][0]+a[0][1]*b[1][0]) m[0].append (a[0][0]*b [0] [1]+a[0][1]*b[1][1]) m[1].append (a[1][0]*b[0][0]+a[1][1]*b[1][0]) m[1].append (a[1][0]*b[1][0]+a[1][1]* B[1][1]) return m def m2 (A, b): m=[] m.append (a[0][0]*b[0][0]+a[0][1]*b[1][0]) m.append (a[1][0]*b[ 0][0]+a[1][1]*b[1][0]) return m return m2 (reduce (m1,[[[0,1],[1,1]) for I in range (n)]), [[0],[1]]) [0]

Description

This code is not as clear as the previous code, so first introduce the following principle (requires a bit of linear algebra knowledge):

First look at the previous iteration version of the Fibonacci function, it is easy to find that there is a transformation: y->x, X+y->y. A different angle is [x,y]->[y,x+y].

Here, I declare a two-dollar vector [x,y]t, which is obtained by a transform [y,x+y]t, which can easily get the transformation matrix is [[1,0],[1,1]], that is to say: [[1,0],[1,1]]*[x,y]t=[y,x+y]t

Make two Yuan Matrix a=[[1,0],[1,1]], two yuan vector x=[0,1]t, easy to know the result of Ax is the next Fibonacci value, namely:

AX=[FIB (1), FIB (2)]t

There are also:

AX=[FIB (2), FIB (3)]t

..................

And so on, you can get:

AⁿX=[FIB (n), fib (n-1)]t

That is, you can get the FIB (n) by the N-0,1]t of the two-ary vector [b], resulting in [FIB (n), fib (n+1)]t.

Here I define a two-ary matrix multiplication function M1, and a transform M2 on a two-ary vector, and then use the reduce operation to complete a multiplication operation to get aⁿx, and finally get the FIB (n).

9) Python programmer ready to participate in ACM contest:

def fib (n): lhm=[[0,1],[1,1] [rhm=[[0],[1]] em=[[1,0],[0,1]] #multiply-matrixes def matrix_mul (LHM,RHM): # Initialize an empty matrix filled with zero result=[[0 for I in range (len (rhm[0]))] for J in Range (Len (RHM))] #mul Tiply Loop for i in range (len (LHM)): For J in Range (Len (rhm[0)): For K in range (len (RHM)): Result[i][j] +=LHM[I][K]*RHM[K][J] return result def matrix_square (MAT): return Matrix_mul (mat,mat) #quick transform def fib_iter (mat,n): if not n: return em elif (n%2): return Matrix_mul (Mat,fib_iter (mat,n-1)) else: return Matrix_square (Fib_iter (MAT,N/2)) return Matrix_mul (Fib_iter (lhm,n), RHM) [0][0]

Description

It is easier to understand this version of the previous FIB function, and this version also uses a two-yuan transformation to find FIB (n). But the difference is that the complexity of this version is LGN, and the previous version is linear.

This version of the difference is that it defines a matrix of fast exponentiation operation Fib_iter, the principle is very simple, can be analogous to the natural number of the fast exponentiation method, so there is not much to say.

PS: Although said to be ACM version, but to tell the truth I never participated in that thing, after all, my algorithm is too water, the thing is too high-end ... Only here yy Bird ~

In Python, the most basic kind of recursion (FIB1) is too inefficient, as long as the n number is large, the computation time is long, and by saving the calculation to a dict, which is then used directly in the calculation, it becomes a memo (memo), as shown in the following FIB2 function. You will find that efficiency is greatly improved.

Within the n=10, FIB1 and fab2 running time are very short to see the difference, but when n=40, it is too obvious, Fib1 run took 35 seconds, FAB2 run only spent 0.00001 seconds.

N=40, the output is as follows:

jay@jay-linux:~/workspace/python.git/py2014$ python fibonacci.py 2014-10-16 16:28:35.176396fib1 (40) = 1023341552014-10-16 16:29:10.479953fib2 (40) =1023341552014-10-16 16:29:10.480035

The two functions that calculate the Fibonacci sequence are as follows: https://github.com/smilejay/python/blob/master/py2014/fibonacci.py

Import Datetimedef FIB1 (n): if n = = 0: return 0 elif n = = 1: return 1 else: return fib1 (n-1) + F IB1 (n-2) known = {0:0, 1:1} def fib2 (n): if n in known: return known[n] res = FIB2 (n-1) + fib2 (n-2)
known[n] = res return resif __name__ = = ' __main__ ': n = all print (Datetime.datetime.now ()) print ( ' Fib1 (%d) =%d '% (n, FIB1 (n)) "Print ( Datetime.datetime.now ())) print (' Fib2 (%d) =%d '% (n, fib2 (n) )) Print (Datetime.datetime.now ())

**Postscript:**

As a result of learning python not long, so the mastery of its various characteristics is not skilled. Rather than writing a program in Python, I'm using c,c++,c# or scheme to write a program. As for the legendary pythonic, I have no experience at the moment, after all, there is no use Python to write any real program.

Learning Python and core Python are good Python starter books that are better suited for people who don't have a programming foundation to read.

Python is the best beginner programming language to start with, not one of them. So it can replace scheme as an introductory language for computer programming at MIT.

**