Cada término de la secuencia de Fibonacci se genera sumando los dos anteriores. Empezando con 1 y 2, los primeros 10 términos son:
Encuentra la suma de los términos pares cuyo valor no exceda 4.000.000.
Entendiendo Fibonacci
La secuencia de Fibonacci es una de las más famosas en matemáticas. Cada número es la suma de los dos anteriores.
Construyendo la secuencia
Empezamos con 1 y 2
Estos son los dos primeros términos dados
1 + 2 = 3
El tercer término es la suma de los dos anteriores
2 + 3 = 5, luego 3 + 5 = 8...
Seguimos sumando: 1, 2, 3, 5, 8, 13, 21, 34...
Identificando los pares
¿Cuáles son pares?
De los primeros 10: 2, 8, 34 son divisibles por 2
Patrón: cada 3 términos
Los pares aparecen en posiciones 2, 5, 8, 11... (cada 3 términos)
Verificación manual
Si sumamos los pares menores que 100: 2 + 8 + 34 = 44
Hay muchos términos pares menores que 4 millones. Necesitamos código.
Conceptos clave
La estrategia
Generar términos de Fibonacci uno a uno, comprobar si son pares, y sumarlos mientras no excedan 4 millones.
Importante: No hay una única forma "correcta" de escribir esto. Aquí verás tres variantes que hacen exactamente lo mismo. Elige la que te resulte más clara.
Variante A: while True + break
Un bucle infinito que rompemos cuando el término excede el límite. Muy explícita, muestra claramente cuándo paramos.
Variante B: while con condición
La condición de salida va directamente en el while. Más limpia, sin break.
Variante C: con función generadora
Separamos la generación de Fibonacci en una función. Más modular y reutilizable.
¿Cuál elegir?
| Variante | Líneas | Ventaja | Cuándo usarla |
|---|---|---|---|
| A: while True + break | 14 | Muy explícita | Cuando quieres ver cada paso |
| B: while con condición | 9 | Compacta | Uso general |
| C: con función | 14 | Modular | Cuando necesitas reutilizar |
Conceptos clave
a, b = 1, 2
Asignación múltiple. Python permite asignar varios valores en una línea. Los dos términos iniciales de Fibonacci.
a, b = b, a + b
Swap pythónico. Avanza la secuencia: a toma el valor de b, y b toma a + b. Todo en una línea, sin variable temporal.
a % 2 == 0
Test de paridad. Si el resto de dividir por 2 es 0, el número es par.
def fibonacci_hasta(limite):
Definir función. Encapsulamos lógica para reutilizarla. limite es un parámetro.
resultado.append(a)
Añadir a lista. El método append agrega un elemento al final de la lista.
Conceptos de Python aprendidos
Generadores en Python
Un generador produce valores bajo demanda usando yield.
No guarda todos los valores en memoria, los genera uno a uno.
Desglose
yield a
"Produce" un valor y pausa la función. La próxima vez que se pida un valor, continúa desde aquí.
takewhile(condición, iterable)
De itertools. Toma elementos mientras la condición sea verdadera. Cuando falla, para.
lambda x: x <= 4000000
Función anónima. Devuelve True si x no excede 4 millones.
sum(f for f in fibs if f % 2 == 0)
Generator expression con filtro. Suma solo los pares.
| Aspecto | Fuerza bruta | Pythónico |
|---|---|---|
| Generación | Manual con while | yield + generador |
| Límite | Condición en while | takewhile |
| Filtrado | if con bloque |
if en generador |
| Memoria | O(1) o O(n) | O(1) siempre |
Conceptos aprendidos
Patrón de los pares
Observación clave: en Fibonacci, cada tercer término es par.
Recurrencia de pares
Si llamamos E(n) al n-ésimo Fibonacci par, existe una recurrencia directa:
Demostración
Verificamos con los primeros términos
E(3) = 4×8 + 2 = 34 ✓
E(4) = 4×34 + 8 = 144 ✓
Ventaja
No necesitamos generar los impares ni comprobar paridad. Saltamos directamente de par en par.
Comparativa de rendimiento
| Método | Iteraciones (4M) | Iteraciones (10¹⁸) | Complejidad |
|---|---|---|---|
| Fuerza bruta | 33 | ~87 | O(log n) |
| Solo pares | 11 | ~29 | O(log n / 3) |
Fibonacci crece exponencialmente, así que incluso la fuerza bruta es O(log n). Pero la versión matemática hace 3× menos iteraciones.