I am following the go tour on their official website and I have been asked to write a Fibonacci generator. Here it 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 consider it very ugly and I'm sure there has to be a better solution. I have been thinking about posting this on the code-review however since I'm asking for a better approach I thought this is the right place to post it.
Is there a better way to write this code?
Here is the task:
Implement a fibonacci function that returns a function (a closure) that returns successive fibonacci numbers.
Here is what we are to do: "Implement a javascript Fibonacci numbers using closures. Specifically, write an function that stores two consecuitive Fibonacci numbers, initially 0 and 1. The function also defines and returns a nested function getNext().
A closure is a special type of anonymous function that references variables declared outside of the function itself. It is similar to accessing global variables which are available before the declaration of the function. Example: // Golang program to illustrate how.
My favorite clean way to implement iterating through the Fibonacci numbers is to use first
as fi - 1, and second
as fi. The Fibonacci equation states that:
fi + 1 = fi + fi - 1
Except when we write this in code, in the next round we're incrementing i
. So we're effectively doing:
fnext i = fcurrent i + fcurrent i - 1
and
fnext i - 1 = fcurrent i
The way I like to implement this in code is:
first, second = second, first + second
The first = second
part corresponds to updating fnext i - 1 = fcurrent i, and the second = first + second
part corresponds to updating fnext i = fcurrent i + fcurrent i - 1.
Then all we have left to do is return the old value of first, so we'll store it in a temp variable out of the way before doing the update. In total, 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 it in action on the Go Playground.
A small trick
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
a := 0
b := 1
return func() int {
a, b = b, a+b
return b-a
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
Another approach
func fibonacci() func() int {
n1, n := -1, 1
return func() int {
n1, n = n, n1+n
return n
}
}
The Go Playground
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With