Fibonacci close

I follow the tour on my official website and I was asked to write a Fibonacci generator. Here he is:

package main import "fmt" // fibonacci is a function that returns // a function that returns an int. func fibonacci() func() int { first := 0 second := 0 return func() int{ if(first == 0) { first = 1 second = 1 return 0 }else { current := first firstc := second second = first + second first = firstc return current } } } func main() { f := fibonacci() for i := 0; i < 10; i++ { fmt.Println(f()) } } 

It works. However, I find this very ugly, and I'm sure there should be a better solution. I was thinking of posting this in a code review, since I am asking for a better approach, I thought this was a good place to post.

Is there a better way to write this code?

Here is the task:

Implement a fibonacci function that returns a function (closure) that returns consecutive fibonacci numbers.

+11
source share
7 answers

My favorite clean way to implement iteration over Fibonacci numbers is to use first as f i - 1 and second as f i . The Fibonacci equation states that:

f i + 1 = f i + f i - 1

Unless we write this in code, in the next round we increase i . So, we effectively do:

f next i = f current i + f current i - 1

and

f next i - 1 = f current i - 1

How do I implement this in code:

 first, second = second, first + second 

The first = second corresponds to the update f next i - 1 = f current i - 1 , and the second = first + second corresponds to the update f next i = f current i + f current i - 1 .

Then all that remains for us to do is return the old value to first, so we will save it in the temp variable before doing the update. As a result, we get:

 // fibonacci returns a function that returns // successive fibonacci numbers from each // successive call func fibonacci() func() int { first, second := 0, 1 return func() int { ret := first first, second = second, first+second return ret } } 

See in action on the go playground .

+37
source

I would use multiple assignment, reduce the length of identifiers, and delete this if statment:

 func fibonacci() func() int { var a, b int b = 1 return func() int { ret := a a, b = b, a+b return ret } } 
+4
source

Another approach

 func fibonacci() func() int { n1, n := -1, 1 return func() int { n1, n = n, n1+n return n } } 

Playground go go

+3
source
 package main import "fmt" // fibonacci is a function that returns // a function that returns an int. func fibonacci() func() int { a, b, sum := 1, 1, 0 return func() int { a,b = b,sum sum = a + b return b } } func main() { f := fibonacci() for i := 0; i < 10; i++ { fmt.Println(f()) } } 
0
source

In addition to the answers already provided, you can also use the snooze function for this:

 package main import "fmt" // fibonacci is a function that returns // a function that returns an int. func fibonacci() func() int { secondLast := 0 last := 1 return func() int { defer func() { secondLast, last = last, secondLast+last }() return secondLast } } func main() { f := fibonacci() for i := 0; i < 10; i++ { fmt.Println(f()) } } 

Go playground

But I think the answers from jwoodalls are the most effective.

Edit: But if you want to use unsigned integers (to show how many Fibonacci numbers you can calculate in your architecture;)), you will have to use either an approach with a variable containing the return value or a defer function.

 package main import "fmt" // fibonacci is a function that returns // a function that returns an uint. func fibonacci() func() uint { var secondLast uint var last uint = 1 return func() uint { defer func() { secondLast, last = last, secondLast + last }() return secondLast } } func main() { f := fibonacci() for i := 0; i < 10; i++ { fmt.Println(f()) } } 

Go playground

EditEdit: Or better yet: use float64 !!!

 package main import "fmt" // fibonacci is a function that returns // a function that returns an float64. func fibonacci() func() float64 { var secondLast float64 var last float64 = 1 return func() float64 { defer func() { secondLast, last = last, secondLast+last }() return secondLast } } func main() { f := fibonacci() for i := 0; i < 10; i++ { fmt.Println(f()) } } 

Go playground

0
source

Or you can use this approach ... simple and straightforward, although not very different from previous answers.

 package main import "fmt" // fibonacci is a function that returns // a function that returns an int. func fibonacci() func() int { f1 := 0 f2 := 1 return func() int { temp := f1+f2 temp2 := f1 f1 = f2 f2 = temp return temp2 } } func main() { f := fibonacci() for i := 0; i < 10; i++ { fmt.Println(f()) } } 
0
source
 package main import "fmt" // fibonacci is a function that returns // a function that returns an int. func fibonacci() func() int { first:=0 second:=0 return func() int{ if second == 0 { second = 1 } else if first == 0 { first = 1 } else { first, second = second, first + second } return second } } func main() { f := fibonacci() for i := 0; i < 10; i++ { fmt.Println(f()) } } 
-1
source

Source: https://habr.com/ru/post/974321/


All Articles