-
-
Save weppos/7843653 to your computer and use it in GitHub Desktop.
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()) | |
} | |
} |
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
}
}
My version:
func fibonacci() func() int {
a, b := 1, 0
return func() int {
a, b = b, a+b
return a
}
}
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))
}
}
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
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.
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())
}
}
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())
}
}```
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())
}
}
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())
}
}
Using defer
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
cum1 := 0
cum2 := 1
return func() int {
defer func() { cum1, cum2 = cum2, cum1+cum2 }()
return cum1
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
I like your answer! I can do fib
numbers but a bit tricky with this problem with closures. Thank you for your answer!
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())
}
}
hehe basically we all disagree about variables names 😄
package main
import "fmt"
// fibonacci is a fucntion that returns
// a function that returns an int.
func fibonacci() func() int {
current, next := 0, 1
return func() int {
fib := current
current, next = next, current+next
return fib
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
P.S.: The solution with the defer
statement is pure gold 🥇
P.S.: The solution with the
defer
statement is pure gold 🥇
Could you please elaborate on what's so special about using defer here? I do not see any improvement over not using it.
Could you please elaborate on what's so special about using defer here? I do not see any improvement over not using it.
two things:
- When I was solving the exercise, using
defer
never crossed my mind, so when I saw that solution it was anahá moment
🤯 - I saw it as a readability improvement for sure, the combination between
Function closures
(link) and thedefer
statement, imho it's way simpler to read:
func fibonacci() func() int {
current, next := 0, 1
return func() int {
defer func() {
current, next = next, current+next
}()
return current
}
}
@pabloxio, I think I understand now how it works (the trick is that values will be updated after current
is returned), but I do not really see any improvement between the defer
approach and something like this:
func fibonacci() func() int {
curr, next := 1, 0
return func() int {
curr, next = next, curr + next
return curr
}
}
Am I missing something?
Thanks for sharing. I think this version can be easily understandable for any one :)