El cociente por 11 es igual a la suma de los cuadrados de sus cifras

El enunciado del problema 1 de la Olimpiada Internacional de Matemáticas de 1960 es el siguiente

Encontrar todos los números de tres cifras para los que al dividir el número entre 11 se obtiene la suma de los cuadrados de las cifras del número inicial.

Diremos que un número x es especial si al dividir x entre 11 se obtiene la suma de los cuadrados de las cifras de x.

Definir la función

tal que (esEspecial x) se verifica si x es especial. Por ejemplo,

Usando la función esEspecial, calcular la respuesta al problema de la Olimpiada.

Calculando los números especiales menores que 10⁶, conjeturar que el conjunto de los números especiales es finito y comprobar la conjetura con QuickCheck.

Soluciones

Nuevas soluciones

  • En los comentarios se pueden escribir nuevas soluciones.
  • El código se debe escribir entre una línea con <pre lang="haskell"> y otra con </pre>

Últimos dígitos de una sucesión

El enunciado del problema 1 de la Fase Local de la Olimpiada Matemática Española del 2000 es

Considérese la sucesión definida como a(1) = 3, y a(n+1) = a(n) + a(n)². Determínense las dos últimas cifras de a(2000).

Definir las sucesiones

tales que

  • sucesionA es la lista de los términos de la sucesión a(n). Por ejemplo,

  • sucesionB es la lista de los dos últimos dígitos de los término de la sucesión a(n). Por ejemplo,

Usando la sucesionB, calcular la respuesta a la pregunta del problema de la Olimpiada.

Soluciones

[schedule on=’2021-05-28′ at=»06:00″]

Nuevas soluciones

  • En los comentarios se pueden escribir nuevas soluciones.
  • El código se debe escribir entre una línea con <pre lang="haskell"> y otra con </pre>

Sumas y productos de dígitos

El enunciado de un problema 3 de la Fase Local de la Olimpiada Matemática Española del
2000
es

¿Cuántos números, comprendidos entre 1.000 y 9.999, verifican que la suma de sus cuatro dígitos es mayor o igual que el producto de los mismos? ¿Para cuántos de ellos se verifica la igualdad?

Definir las funciones

tales que

  • (conMayorSumaQueProducto a b) es la lista de los números del intervalo [a,b] tales que la suma de sus dígitos es mayor que el producto de los mismos. Por ejemplo,

  • (conIgualSumaQueProducto a b) es la lista de los números del intervalo [a,b] tales que la suma de sus dígitos es igual que el producto de los mismos. Por ejemplo,

Usando las funciones anteriores, calcular las respuestas a las preguntas del problema de la Olimpiada.

Soluciones

[schedule on=’2021-05-27′ at=»06:00″]

Nuevas soluciones

  • En los comentarios se pueden escribir nuevas soluciones.
  • El código se debe escribir entre una línea con <pre lang="haskell"> y otra con </pre>

Números suma de dos cuadrados

El enunciado del problema 3.3 de la Fase Local de la Olimpiada Matemática Española del 2004 es

Hallad todas las posibles formas de escribir 2003 como suma de dos cuadrados de números enteros positivos.

Definir la sucesión

cuyos elementos son los números que se pueden expresar como suma de los cuadrados de dos números naturales. Por ejemplo,

Comprobar con QuickCheck las siguientes propiedades:

  • La sucesión sonSumaDosCuadrados es infinita.
  • Los elementos de sonSumaDosCuadrados no son congruentes con 3 módulo 4 (es decir, sus restos al dividirlo por 4 son distintos de 3).

Usando sonSumaDosCuadrados, resolver el problema propuesto; es decir, calcular todas las posibles formas de escribir 2003 como suma de dos cuadrados de números enteros positivos.

Soluciones

<

pre lang=»haskell»>
import Test.QuickCheck (Property, (==>), quickCheck)

— 1ª solución
— ===========

sonSumaDosCuadrados :: [Integer]
sonSumaDosCuadrados =
filter esSumaDeDosCuadrados [0..]

— (esSumaDeDosCuadrados) se verifica si n se puede escribir como la
— suma de los cuadrados de dos números naturales. Por ejemplo,
— esSumaDeDosCuadrados 5 == True
— esSumaDeDosCuadrados 3 == False
esSumaDeDosCuadrados :: Integer -> Bool
esSumaDeDosCuadrados = not . null . descomposicionesSumaDosCuadrados

— (descomposicionesSumaDosCuadrados n) es la lista de pares de
— cuadrados de números naturales (con la primera componente menor o
— igual que la segunda) cuya suma es n. Por ejmplo,
— descomposicionesSumaDosCuadrados 3 == []
— descomposicionesSumaDosCuadrados 4 == [(0,4)]
— descomposicionesSumaDosCuadrados 5 == [(1,4)]
— descomposicionesSumaDosCuadrados 25 == [(0,25),(9,16)]
— descomposicionesSumaDosCuadrados 325 == [(1,324),(36,289),(100,225)]
— descomposicionesSumaDosCuadrados 1105 == [(16,1089),(81,1024),(144,961),(529,576)]
descomposicionesSumaDosCuadrados :: Integer -> [(Integer,Integer)]
descomposicionesSumaDosCuadrados n =
[(a,b) | a <- xs,
let b = n – a,
b elem xs,
a <= b]
where xs = takeWhile (<= n) cuadrados

— cuadrados es la lista de los cuadrados. Por ejemplo,
— take 10 cuadrados == [0,1,4,9,16,25,36,49,64,81]
cuadrados :: [Integer]
cuadrados = map (^2) [0..]

— 2ª solución
— ===========

sonSumaDosCuadrados2 :: [Integer]
sonSumaDosCuadrados2 =
filter esSumaDeDosCuadrados2 [0..]

esSumaDeDosCuadrados2 :: Integer -> Bool
esSumaDeDosCuadrados2 = not . null . descomposicionesSumaDosCuadrados2

descomposicionesSumaDosCuadrados2 :: Integer -> [(Integer,Integer)]
descomposicionesSumaDosCuadrados2 n =
[(a,b) | a <- ys,
let b = n – a,
b elem m : zs]
where m = n div 2
xs = takeWhile (<= n) cuadrados
(ys,zs) = span (<= m) xs

— 3ª solución
— ==========

sonSumaDosCuadrados3 :: [Integer]
sonSumaDosCuadrados3 =
mezclaTodas [[n^2+k^2 | k <- [n..]] | n <- [0..]]

— (mezclaTodas xss) es la mezcla ordenada de xss, donde tanto xss como
— sus elementos son listas infinitas ordenadas. Por ejemplo,
— λ> take 10 (mezclaTodas [[n,2n..] | n <- [2..]]) -- [2,3,4,5,6,7,8,9,10,11] -- λ> take 10 (mezclaTodas [[n,2n..] | n <- [2,9..]])
— [2,4,6,8,9,10,12,14,16,18]


mezclaTodas :: Ord a => [[a]] -> [a]
mezclaTodas = foldr1 xmezcla
where xmezcla (x:xs) ys = x : mezcla xs ys

— (mezcla xs ys) es la mezcla de las listas infinitas ordenadas xs es
— ys. Por ejemplo,
— take 10 (mezcla [1,3..] [4,8..]) == [1,3,4,5,7,8,9,11,12,13]
mezcla :: Ord a => [a] -> [a] -> [a]
mezcla (x:xs) (y:ys) | x < y = x : mezcla xs (y:ys)
| x == y = x : mezcla xs ys
| x > y = y : mezcla (x:xs) ys

— Comprobación de equivalencia
— ============================

— La comprobación es
— λ> take 1000 sonSumaDosCuadrados == take 1000 sonSumaDosCuadrados2
— True
— λ> take 1000 sonSumaDosCuadrados2 == take 1000 sonSumaDosCuadrados3
— True

— Comparación de eficiencia
— =========================

— La comparación es
— λ> sonSumaDosCuadrados !! (510^3)
— 18973
— (2.29 secs, 266,485,976 bytes)
— λ> sonSumaDosCuadrados2 !! (5
10^3)
— 18973
— (1.01 secs, 473,019,976 bytes)
— λ> sonSumaDosCuadrados3 !! (5*10^3)
— 18973

— (0.17 secs, 103,957,288 bytes)

— λ> sonSumaDosCuadrados2 !! (510^4)
— 216090
— (78.14 secs, 17,856,157,080 bytes)
— λ> sonSumaDosCuadrados3 !! (5
10^4)
— 216090
— (4.23 secs, 3,325,056,480 bytes)

— Propiedades
— ===========

— La primera propiedad es
prop_infinitud :: Integer -> Bool
prop_infinitud n =
(not . null) (dropWhile (<= n) sonSumaDosCuadrados3)

— Su comprobación es
— λ> quickCheck prop_infinitud
— +++ OK, passed 100 tests.

— La segunda propiedad es
prop_modulo4 :: Int -> Property
prop_modulo4 k =
k >= 0 ==>
(sonSumaDosCuadrados3 !! k) mod 4 /= 3

— Su comprobación es
— λ> quickCheck prop_modulo4
— +++ OK, passed 100 tests.

— 4ª solución
— ===========

— Basada en la 2ª propiedad.

sonSumaDosCuadrados4 :: [Integer]
sonSumaDosCuadrados4 =
filter esSumaDeDosCuadrados4 [0..]

esSumaDeDosCuadrados4 :: Integer -> Bool
esSumaDeDosCuadrados4 = not . null . descomposicionesSumaDosCuadrados4

descomposicionesSumaDosCuadrados4 :: Integer -> [(Integer,Integer)]
descomposicionesSumaDosCuadrados4 n
| n mod 4 == 3 = []
| otherwise = [(a,b) | a <- ys,
let b = n – a,
b elem m : zs]
where m = n div 2
xs = takeWhile (<= n) cuadrados
(ys,zs) = span (<= m) xs

— Comprobación de equivalencia
— ============================

— La comprobación es
— λ> take 1000 sonSumaDosCuadrados3 == take 1000 sonSumaDosCuadrados4
— True

— Comparación de eficiencia
— =========================

— La comparación es
— λ> sonSumaDosCuadrados2 !! (10^4)
— 39593
— (3.60 secs, 1,413,851,720 bytes)
— λ> sonSumaDosCuadrados3 !! (10^4)
— 39593
— (0.42 secs, 284,603,104 bytes)
— λ> sonSumaDosCuadrados4 !! (10^4)
— 39593
— (2.58 secs, 1,043,995,480 bytes)

— Cálculo para resolver el problema
— =================================

— El cálculo es
— λ> 2003 == head (dropWhile (<2003) sonSumaDosCuadrados3)
— False
— Por tanto, no es posible escribir 2003 como suma de dos cuadrados de
— números enteros positivos.

Nuevas soluciones

  • En los comentarios se pueden escribir nuevas soluciones.
  • El código se debe escribir entre una línea con <pre lang="haskell"> y otra con </pre>

Ternas aditivas

El enunciado del problema C6 de la Fase Local de la Olimpiada Matemática Española del 2006 es

Decimos que tres números naturales distintos forman una terna aditiva si la suma de los dos primeros de ellos es igual al tercero. Hallar, razonadamente, el máximo número de ternas aditivas que puede haber en un conjunto dado de 20 números naturales.

Definir las funciones

tales que

  • (ternasAditivas n) es la lista de las ternas aditivas crecientes que se pueden formar con los n primeros números enteros positivos. Por ejemplo,

  • (nTernasAditivas n) es el número de ternas aditivas crecientes que se pueden formar con los n primeros números enteros positivos. Por ejemplo,

Soluciones

Nuevas soluciones

  • En los comentarios se pueden escribir nuevas soluciones.
  • El código se debe escribir entre una línea con <pre lang="haskell"> y otra con </pre>