Sucesiones auto descriptivas en Haskell

En las Olimpiadas de Matemáticas del 2001 se propuso el siguiente problema

Buscar todas las sucesiones finitas (x(0), x(1),…,x(n)) tales que para todo j, 0 ≤ j ≤ n, x(j) es igual al número de veces que aparece j en la sucesión.

Las sucesiones que cumplen la anterior condición se llaman auto descriptivas. Un ejemplo de sucesión auto descriptiva es [5,2,1,0,0,1,0,0,0] ya que

  • el 0 aparece 5 veces,
  • el 1 aparece 2 veces,
  • el 2 aparece 1 vez,
  • el 3 aparece 0 veces,
  • el 4 aparece 0 veces,
  • el 5 aparece 1 vez,
  • el 6 aparece 0 veces,
  • el 7 aparece 0 veces y
  • el 8 aparece 0 veces.

En la siguiente relación de ejercicios, elaborada para la asignatura de Informática (de 1º del Grado en Matemáticas) y para la siguiente versión del libro Piensa en Haskell, se resuelve el problema con Haskell.
Read More “Sucesiones auto descriptivas en Haskell”

El problema de las sucesiones llenas en Haskell

En las Olimpiadas de Matemáticas del 2002 se propuso el siguiente problema

Sea n un entero positivo. Una sucesión de n enteros positivos (no necesariamente distintos) se llama “llena” si verifica la siguiente condición: para cada entero positivo k ≥ 2, si el número k aparece en la sucesión, entonces también lo hace el número k-1 y, además, la primera ocurrencia de k-1 es anterior a la última ocurrencia de k. Para cada n, ¿cuántas sucesiones llenas existen?

En la siguiente relación de ejercicios, elaborada para la asignatura de Informática (de 1º del Grado en Matemáticas), se estudia con Haskell el problema.
Read More “El problema de las sucesiones llenas en Haskell”

I1M2012: Ceros finales del factorial

En 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 de 1987 cuyo enunciado es

”Calcular el menor número natural n tal que n! termina exactamente en 1987 ceros.”

Resolverlo con Haskell.

Para resolverlo, empezamos definiendo la función cerosDelFactorial tal que (cerosDelFactorial n) es el número de ceros en que termina el factorial de n. Por ejemplo,

Presentamos dos definiciones la primera es

donde (ceros n) es el número de ceros en los que termina el número n. Por ejemplo,

y (factorial n) es el factorial n. Por ejemplo,

La segunda es

Se puede comprobar la equivalencia de las dos definiciones

y que la segunda es más eficiente

En lo que sigue, usaremos la segunda definición

A continuación definimos la función menorFactorial tal que (menorFactorial m) es el menor número cuyo factorial termina en m ceros exactamente. Por ejemplo,

Finalmente definimos la solución del problema; es decir, el menor número natural n tal que n! termina exactamente en 1987 ceros.

El cálculo de la solución es

I1M2012: Suma de números monótonos

En 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 de 1982 cuyo enunciado es

Calcular la suma de todos los enteros positivos cuyos dígitos forman una sucesión estrictamente creciente o estrictamente decreciente.

Lo resolveremos generando las listas de todos los enteros positivos cuyos dígitos forman una sucesión estrictamente monótona. Para ello nos basaremos en las listas de dígitos que forman una sucesión estrictamente monótona.

Comenzamos con los decrecientes:

  • (listasDecrecientesDesde n) es la lista de las sucesiones estrictamente decrecientes cuyo primer elemento es n. Por ejemplo,
    ghci> listasDecrecientesDesde 3
    [[3],[3,2],[3,2,1],[3,2,1,0],[3,2,0],[3,1],[3,1,0],[3,0]]

  • listasDecrecientes es la lista de las sucesiones estrictamente decrecientes cuyo primer elemento es un dígito. Por ejemplo,
    ghci> take 10 listasDecrecientes
    [[0],[1],[1,0],[2],[2,1],[2,1,0],[2,0],[3],[3,2],[3,2,1]]

  • (listaNumero xs) es el número correspondiente a la lista de dígitos xs. Por ejemplo,
    listaNumero [3,2,5] == 325

  • numerosDecrecientes es la lista de los enteros positivos cuyos dígitos forman una sucesión estrictamente decreciente. Por ejemplo,
    ghci> take 17 numerosDecrecientes
    [0,1,10,2,21,210,20,3,32,321,3210,320,31,310,30,4,43]

    Análogamente se construyen los crecientes:

  • (listasCrecientesDesde n) es la lista de las sucesiones estrictamente crecientes cuyo primer elemento es n. Por ejemplo,
    ghci> listasCrecientesDesde 6
    [[6],[6,7],[6,7,8],[6,7,8,9],[6,7,9],[6,8],[6,8,9],[6,9]]

  • listascrecientes es la lista de las sucesiones estrictamente crecientes cuyo primer elemento es un dígito. Por ejemplo,
    ghci> take 5 listasCrecientes
    [[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5]]

  • numerosCrecientes es la lista de los enteros positivos cuyos dígitos forman una sucesión estrictamente creciente. Por ejemplo,
    ghci> take 5 numerosCrecientes
    [1,12,123,1234,12345]

    Con las definiciones anteriores la solución es inmediata:

    El cálculo de la solución es

I1M2012: Número con mayor cantidad de divisores

En la primera 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 de 1983. Su enunciado es

”¿Cuál de los números 1, 2, …, 1983 tiene mayor número de divisores?”

Se van a presentar distintas soluciones y comparar sus eficiciencias. La primera definición es

donde (divisores1 n) es el conjunto de los divisores de n.

El cálculo con la primera definición es

En la segunda definición se cambia la definición de divisores

El cálculo con la segunda definición es

En la tercera definición se ordenan los pares

El cálculo con la tercera definición es

Se observa que el tiempo se ha reducido de 9.00 segundos a 2.76.