Last active
March 25, 2024 23:03
-
-
Save weppos/7843653 to your computer and use it in GitHub Desktop.
A Tour of Go Exercise: Fibonacci closure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "fmt" | |
// fibonacci is a function that returns | |
// a function that returns an int. | |
func fibonacci() func() int { | |
f2, f1 := 0, 1 | |
return func() int { | |
f := f2 | |
f2, f1 = f1, f+f1 | |
return f | |
} | |
} | |
func main() { | |
f := fibonacci() | |
for i := 0; i < 10; i++ { | |
fmt.Println(f()) | |
} | |
} |
one letter variables is evil (except loop var)
traditional
func fibonacci() func() int {
current := 0
next := 1
return func() int {
current, next = next, current+next
return current
}
}
with defer
func fibonacci() func() int {
current := 1
next := 1
return func() int {
defer func() {
current, next = next, current+next
}()
return current
}
}
package main
import "fmt"
func fibonacci() func() []int {
arr := make([]int,0)
return func() []int {
switch len(arr){
case 0:
arr = append(arr,0)
case 1:
arr = append(arr,1)
default:
arr = append(arr,arr[len(arr)-1]+ arr[len(arr)-2])
}
return arr
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
Here is my solution -
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
x, y := 0, 1
return func() int{
x++
y++
return (x-1)+(y-2)
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
Not as elegant but doing the job:
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
i := -1
f1 := 0
f2 := 1
return func() int {
switch i+=1; i {
case 0:
return 0
case 1:
return 1
default:
f := f1 + f2
f1 = f2
f2 = f
return f
}
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
We can omit the variable f with
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
f1, f2 := 0, 1
return func() int {
f1, f2 = f2, f1+f2
return f1
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
similar to other solutions using if statements
Hope it helps someone out there
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func(int) int {
prev2 := 0
prev1 := 1
return func(x int ) int{
sum:=0
//SKIPPING FIRST 2 ITTERATION
if x == 0{
return 0
}else if x == 1{
return 1
}else{
//Staring at 2 value should still be 1
sum = prev1 + prev2
}
//THEN MAKE PREVIOUS VALUES CURRENT FOR NEXT ITTERATION
prev2 = prev1
prev1 = sum
//RETURN THE RESULT
return fib
}
}
func main() {
//Assigning a function fibonacci
f := fibonacci()
//now looping through and passing i each time
for i := 0; i < 10; i++ {
fmt.Println(i,"->",f(i))
}
}
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
f1, f2 := 0, 1
return func() int {
// f is previous fibonacci number
// f() closure actually returns
// previous fibonacci number
f := f1
f1, f2 = f2, f1+f2
return f
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
With defer
func fibonacci() func() int {
var v0, v1 int = 0,1
advance := func () {
v0, v1 = v1, v0+v1
}
return func() int {
defer advance()
return v0
}
}
package main
import "fmt"
func fibonacci() func() uint64 {
a := uint64(0)
b := uint64(0)
c := uint64(a + b)
return func() uint64 {
if c-a > c-b {
c = c + (c - a)
a = c - b
return c
} else if c-a < c-b {
c = c + (c - b)
b = c - a
return c
} else if c == c {
a += 0
b += 1
c += 1
return c
}
return c
}
}
func main() {
f := fibonacci()
for i := 0; i < 1000; i++ {
fmt.Println(f())
}
}
package main
import "fmt"
func fibonacci() func() int {
f := [10]int{0, 1}
i := 0
return func() int {
last := i
i++
if last == 0 || last == 1 {
return f[last]
}
f[last] = f[last-1] + f[last-2]
return f[last]
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
package main
import "fmt"
func fibonacci() func() int {
fib, temp, next := 0, 0, 1
return func() int {
fib = temp
temp = next
next = fib + temp
return fib
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
num := 0
nextNum := 1
advance := func () {
temp := nextNum
nextNum = num + nextNum
num = temp
}
return func () int {
defer advance()
return num
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
f1 := 0
f2 := 1
reFunc := func() int {
f := f1
f1 = f2
f2 = f + f1
return f
}
return reFunc
}
func main() {
f := fibonacci()
for i := 0; i < 100; i++ {
fmt.Println(f())
}
}
package main
import "fmt"
func fibonacci() func() int {
a, b := 1, 0
return func() int {
a, b = b, a + b
return a
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I like your answer! I can do
fib
numbers but a bit tricky with this problem with closures. Thank you for your answer!