Skip to content

Instantly share code, notes, and snippets.

@weppos

weppos/44.go

Last active Aug 26, 2020
Embed
What would you like to do?
A Tour of Go Exercise: Fibonacci closure
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())
}
}
@harryge00

This comment has been minimized.

Copy link

@harryge00 harryge00 commented Jun 6, 2019

excellent!

@dumindu

This comment has been minimized.

Copy link

@dumindu dumindu commented Jun 12, 2019

Thanks for sharing. I think this version can be easily understandable for any one :)

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.

func fibonacci() func() int {
	v1, v2 := 0, 1
	return func() int {
		f := v1
		v1, v2 = v2, v2+f

		return f
	}
}

func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}
@anantxx

This comment has been minimized.

Copy link

@anantxx anantxx commented Jul 15, 2019

Here's my solutions

package main
import (
	"fmt"
	"log"
	"time"
)

func main() {
	defer timeTrack(time.Now(), "Main")
	f := fibonacci()
	for i := 0; i < 100; i++ {
		fmt.Println(f())
	}
}

func timeTrack(start time.Time, name string) {
	elapsed := time.Since(start)
	log.Printf("%s took %s", name, elapsed)
}

/*
Solution 1:
func fibonacci() func() uint {
	var v1, v2 uint = 0, 1
	return func() uint {
		v2 = v2 + v1
		v1 = v2 - v1
		return v2 - v1
	}
}
*/

/*
Solution 2:*/
func fibonacci() func() int {
	v1, v2 := 0, 1

	return func() int {
		defer func() {
			v1, v2 = v2, v1+v2
		}()

		return v1
	}
}

@citaret

This comment has been minimized.

Copy link

@citaret citaret commented Jul 30, 2019

My version:

func fibonacci() func() int {
    a, b := 1, 0
    return func() int {
        a, b = b, a+b
        return a
    }
}
@banothurameshnaik

This comment has been minimized.

Copy link

@banothurameshnaik banothurameshnaik commented Sep 20, 2019

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func(int) int {
	first := 0
	second := 1
	return func(i int) int {
		if i == 0 || i == 1 {
			return i
		}
		sum := first + second
		first = second
		second = sum
		return sum
	}
}

func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f(i))
	}
}
@ptflp

This comment has been minimized.

Copy link

@ptflp ptflp commented Dec 13, 2019

My version:

func fibonacci() func() int {
    a, b := 1, 0
    return func() int {
        a, b = b, a+b
        return a
    }
}

it's not your solution, this solution belongs to @stvr in 2012

@dougahmann

This comment has been minimized.

Copy link

@dougahmann dougahmann commented Feb 2, 2020

func fibonacci() func() int {
	previous := 0
	last := 0
	index := 0
	
	return func() int {
		var result int
		if index == 1 {
			result = 1
		} else {
			result = last + previous	
		}
		
		previous = last;
		last = result;
		index++
		
		return int(result)
	}
}

func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}

This is what I came up, before searching for other's solutions. Mine doesn't modify main(), which I believe was part of the spirit of the exercise. Otherwise, very close to banothurameshnaik's solution.

In any case, I find this more readable than the first example as someone new to Go (but with 30+ years programming experience). Is the bunching of multiple assignments on a line (e.g. a, b := 1, 0) really considered "best practice"? Seems like it's being clever at the expense of readability. Probably biased by my experience with other languages. Maybe my opinion will change over time. Other than slightly less typing and fewer lines, what else would be the advantage of using the shorter notation?

Thanks in advance for any opinions.

@Thargelion

This comment has been minimized.

Copy link

@Thargelion Thargelion commented Mar 26, 2020

This starts with zero and does not modifies main()

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
	a, b := 0, 1
	return func() int {
		result := a // Store the result value before translations
		c := a + b // Fibonacci
		a = b // Translation
		b = c // Translation
		return result
	}
}

func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}
@anuragguptagithub

This comment has been minimized.

Copy link

@anuragguptagithub anuragguptagithub commented Jul 3, 2020


import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    a: = 0
    b: = 1
    sum: = a + b
    return func() int {
        if a == 0 {
            a = b
            return 0
        }
        a = b
        b = sum
        sum = a + b
        return a
    }
}

func main() {
    f: = fibonacci()
    for i: = 0;i < 10;i++{
        fmt.Println(f())
    }
}```
@anuragguptagithub

This comment has been minimized.

Copy link

@anuragguptagithub anuragguptagithub commented Jul 3, 2020


import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
	a, b := 1, 0
	return func() int {
		a, b = b, a+b // two assignment happens parallely, but if you enforce it sequentially, it won't work
		return a
	}
}

func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}
@Wuitar

This comment has been minimized.

Copy link

@Wuitar Wuitar commented Jul 14, 2020

use slice

package main

import "fmt"

func fibonacci() func() int {
	var i []int
	return func() int {
		if len(i) == 0 {
			i = append(i, 0)
		} else if len(i) == 1 {
			i = append(i, 1)
		} else {
			i = append(i, i[len(i)-2]+i[len(i)-1])
		}
		return i[len(i)-1]
	}
}

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
You can’t perform that action at this time.