Médio Go
Gerador de Fibonacci
Enunciado
Implemente uma função geradorFibonacci que retorna uma closure. A closure deve gerar o próximo número da sequência de Fibonacci a cada chamada, começando em 0 e 1. No main, imprima os 10 primeiros números.
Requisitos
- A função
geradorFibonacciretornafunc() int. - A closure mantém os dois últimos valores da sequência.
- Os 10 primeiros números são: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34.
Código inicial
package main
import "fmt"
// geradorFibonacci retorna uma closure que gera números de Fibonacci.
func geradorFibonacci() func() int {
// implemente aqui
return nil
}
func main() {
// crie o gerador e imprima os 10 primeiros números
}
Saída esperada
0
1
1
2
3
5
8
13
21
34
Ver dica
Mantenha duas variáveis a e b (inicialmente 0 e 1). A cada chamada, retorne a e atualize a, b = b, a+b.
Mostrar solução
package main
import "fmt"
// geradorFibonacci retorna uma closure que gera a sequência de Fibonacci.
func geradorFibonacci() func() int {
a, b := 0, 1 // estado inicial
return func() int {
prox := a // guarda o valor a ser retornado
a, b = b, a+b // atualiza para o próximo par
return prox
}
}
func main() {
fib := geradorFibonacci()
for i := 0; i < 10; i++ {
fmt.Println(fib())
}
}
Passo a passo
- Dentro de
geradorFibonacci, declaramosa, b := 0, 1. Essas variáveis representam os dois últimos números da sequência. - Retornamos uma closure que captura
aeb. - Na closure,
prox := aguarda o valor atual antes de atualizar. a, b = b, a+bfaz a troca:arecebe o antigob, ebrecebe a soma. Isso avança a sequência.- Retornamos
prox, que é o número Fibonacci da vez. - No
main, chamamosfib()10 vezes e imprimimos cada resultado. - A sequência começa em 0 e segue corretamente até 34.
Por que funciona
A closure mantém o estado de a e b entre chamadas. Cada chamada atualiza esses valores de forma atômica (para uso single-thread) e retorna o número correto. O uso de atribuição múltipla a, b = b, a+b evita a necessidade de uma variável temporária.
Erros comuns
- Não guardar o valor antes de atualizar: se fizer
a, b = b, a+b; return a, o primeiro retorno seria 1 em vez de 0. - Atualizar
bantes dea:b = a + b; a = b - aé confuso e propenso a erros; prefira a atribuição múltipla. - Usar
inte estourar: para muitos números,intpode estourar; mas para 10 termos é seguro.
Outra forma de resolver
Usar um slice pré-computado não é uma closure, mas resolve o mesmo problema sem estado persistente. A closure é preferível quando se quer gerar sob demanda, sem alocar memória para toda a sequência.
Saída esperada
0
1
1
2
3
5
8
13
21
34