I1M2012: Último dígito del producto de números de Fermat
En la segunda parte de la clase de hoy de Informática de 1º del Grado en Matemáticas hemos comentado la solución con Haskell de un problema propuesto para la Olimpiada Internacional de Matemáticas (IMO) de 1971. Su enunciado es
Sea
y sea
el producto de
. Calcular el último dígito de
.
La primera definición es la traducción directa del enunciado
1 2 |
sol1 :: Integer sol1 = ultimo (product [x n | n <- [2..1971]]) |
donde (x n) es el n-ésimo término de la sucesión
1 2 |
x :: Int -> Integer x n = 2^(2^n) + 1 |
y (ultimo x) es el último dígito de x
1 2 |
ultimo :: Integer -> Integer ultimo x = rem x 10 |
Aunque la primera solución es simple, tiene un inconveniente: Haskell no puede calcular números tan grandes. Una estrategia para resolverlo es considerar casos menores y buscar alguna regularidad. Para ello, generalizamos la primera solución sustituyendo 1971 por una variable.
1 2 |
sol2 :: Int -> Integer sol2 a = ultimo (product [x n | n <- [2..a]]) |
Con la 2ª definición calculamos el último dígito de los primeros productos
1 2 |
ghci> [sol2 a | a <- [2..20]] [7,9,3,1,7,9,3,1,7,9,3,1,7,9,3,1,7,9,3] |
Se observa que el resultado está formado por la repetición de los números 7, 9, 3 y 1. A partir de la observación conjeturamos una nueva definición
1 2 3 4 5 6 |
sol3 :: Int -> Integer sol3 a | b == 2 = 7 | b == 3 = 9 | b == 0 = 3 | b == 1 = 1 where b = rem a 4 |
Podemos comprobar, para pequeños valores, que las 2 definiciones son equivalentes
1 2 |
ghci> [sol2 a | a <- [2..20]] == [sol3 a | a <- [2..20]] True |
Además, con la 3ª definición se puede calcular la solución del problema original
1 2 |
ghci> sol3 1971 9 |
es decir, el último dígito del producto es 9.
Para justificar la solución, hay que demostrar que la definición sol3 es correcta; es decir, que los últimos dígitos de los productos forman la sucesión 7, 9, 3, 1, 7, 9, 3, 1, 7, 9, 3, 1, 7, 9, 3, 1, 7, 9, 3, … Para ello, observamos el último dígito de los
1 2 |
ghci> [ultimo (x n) | n <- [2..20]] [7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7] |
Se observa que todos son 7. Esto justifica la sucesión de los productos, ya que cada término es el último dígito del producto del anterior por 7. Además, permite una nueva definición de la solución por recursión
1 2 3 |
sol4 :: Int -> Integer sol4 a | a == 2 = 7 | otherwise = ultimo (7 * sol4 (a-1)) |
Podemos comprobar, para pequeños valores, que es equivalente a la anterior
1 2 |
ghci> [sol3 a | a <- [2..20]] == [sol4 a | a <- [2..20]] True |
Para terminar, sólo queda demostrar que si , entonces el último dígito de
es 7 o, equivalentemente, que el último dígito de
es 6. Lo que se tiene ya que
. Además, como
se tiene que
es un número par mayor que 0 y, por tanto, el último dígito de
es 6.