División segura

Definir la función

tal que (divisionSegura x y) es x/y si y no es cero y 9999 en caso contrario. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell

El código se encuentra en GitHub.


Soluciones en Python

El código se encuentra en GitHub.

Comentarios

  • El condicional se escribe en Haskell como

y en Python como

  • Una alternativa al uso de los condicionales son los patrones que en Haskell se escribe en los argumentos de las ecuaciones y en Python con match cases.

Tres diferentes

Definir la función

tal que (tresDiferentes x y z) se verifica si los elementos x, y y z son distintos. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell

El código se encuentra en GitHub.


Soluciones en Python

El código se encuentra en GitHub.

Comentarios

  • Para decidir si x e y son distintos, se escribe
    • x /= y en Haskell y
    • x != y en Python.

Tres iguales

Definir la función

tal que (tresIguales x y z) se verifica si los elementos x, y y z son iguales. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell

El código se encuentra en GitHub.


Soluciones en Python

El código se encuentra en GitHub.

Comentarios

  • La conjunción de x e y se calcula
    • en Haskell, con x && y y
    • en Python, con x and y.
  • En Python, x == y == z es equivalente a x == y and y == z.

Elemento mediano

Definir la función

tal que (mediano x y z) es el número mediano de los tres números x, y y z. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell

El código se encuentra en GitHub.


Soluciones en Python

El código se encuentra en GitHub.

Primeros y últimos elementos

Definir la función

tal que (extremos n xs) es la lista formada por los n primeros elementos de xs y los n finales elementos de xs. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell

El código se encuentra en GitHub.


Soluciones en Python

El código se encuentra en GitHub.

Segmento de una lista

Definir la función

tal que (segmento m n xs) es la lista de los elementos de xs comprendidos entre las posiciones m y n. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell

El código se encuentra en GitHub.


Soluciones en Python

El código se encuentra en GitHub.

Elementos finales

Definir la función

tal que (finales n xs) es la lista formada por los n finales elementos de xs. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell

El código se encuentra en GitHub


Soluciones en Python

El código se encuentra en GitHub

Comentarios

  • La longitud de la lista xs se calcula
    • en Haskell, con length xs y
    • en Python, con len(xs).

Interior de una lista

Definir la función

tal que (interior xs) es la lista obtenida eliminando los extremos de la lista xs. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell

El código se encuentra en GitHub.


Soluciones en Python

El código se encuentra en GitHub.

Comentarios

  • Los elementos iniciales de una lista xs se calcula
    • en Haskell, con init xs y
    • en Python, con xs[:-1].

Reconocimiento de palíndromos

Definir la función

tal que (palindromo xs) se verifica si xs es un palíndromo; es decir, es lo mismo leer xs de izquierda a derecha que de derecha a izquierda. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell

El código se encuentra en GitHub.


Soluciones en Python

El código se encuentra en GitHub.

Comentarios

  • La inversa de la lista xs se calcula
    • en Haskell, con reverse xs y
    • en Python, con list(reversed(xs)).
  • Para comparar la igualdad de dos listas xs e ys se escribe igual qh Haskell y en Python: xs == ys.

Rango de una lista

Definir la función

tal que (rango xs) es la lista formada por el menor y mayor elemento de xs. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell

El código se encuentra en GitHub.


Soluciones en Python

El código se encuentra en GitHub.

Comentarios

  • El menor elemento de la lista xs se calcula
    • en Haskell, con minimum xs y
    • en Python, con min(xs).
  • El mayor elemento de la lista xs se calcula
    • en Haskell, con maximum xs y
    • en Python, con max(xs).

Los primeros al final

Definir la función

tal que (rota n xs) es la lista obtenida poniendo los n primeros elementos de xs al final de la lista. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell

El código se encuentra en GitHub.


Soluciones en Python

El código se encuentra en GitHub.

Comentarios
+ Los n primeros elementos de la lista xs se calcula
+ en Haskell, con take n xs y
+ en Python, con xs[n:].
+ La lista xs sin sus n primeros elementos se calcula
+ en Haskell, con drop n xs y
+ en Python, con xs[:n].

El primero al final

Definir la función

tal que (rota1 xs) es la lista obtenida poniendo el primer elemento de xs al final de la lista. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell

El código se encuentra en GitHub.


Soluciones en Python

El código se encuentra en GitHub.

Comentarios

  • El primer elemento de la lista xs se calcula
    • en Haskell, con head xs
    • en Python, con xs[0]
  • El resto de la lista xs se calcula
    • en Haskell, con tail xs
    • en Python, con xs[1:]
  • La concatenación de las listas xse ysse calcula
    • en Haskell, con xs ++ ys
    • en Python, con xs + ys
  • En Python. xs.append(x) modifica la lista xs añadiéndole x al final. Por ejemplo,

Máximo de tres números

Definir la función

tal que (maxTres x y z) es el máximo de x, y y z. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Solución en Haskell

El código se encuentra en GitHub.


Soluciones en Python

El código se encuentra en GitHub.

Comentarios

  • El máximo de x e y se escribe
    • en Haskell, max x y y
    • en Python, max(x, y).

Último dígito

Definir la función

tal que (ultimoDigito x) es el último dígito del número x. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Solución en Haskell

El código se encuentra en GitHub.


Solución en Python

El código se encuentra en GitHub.

Comentarios

  • El resto de la división entera se x entre y sn ecribe
    • en Haskell, rem x y,
    • en Python, x % y.

Área de la corona circular

Definir la función

tal que (areaDeCoronaCircular r1 r2) es el área de una corona circular de radio interior r1 y radio exterior r2. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Solución en Haskell

El código se encuentra en GitHub.


Solución en Python

El código se encuentra en GitHub.

Comentarios

  • La diferencia de dos números x e y se escribe en Python igual que en Haskell: x - y.

Volumen de la esfera

Definir la función

tal que (volumenEsfera r) es el volumen de la esfera de radio r. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Solución en Haskell

El código se encuentra en GitHub.


Solución en Python

El código se encuentra en GitHub.

Comentarios

  • El número \pi se representa igual en Python que en Haskell; pero, en Python. para usarlo hay que importarlo de la librería math.
  • La potencia de número x elevado al entero n se escribe
    • en Haskell, x^n y
    • en Python, x ** n.

Suma de monedas

Definir la función

tal que (sumaMonedas a b c d e) es la suma de los euros correspondientes a a monedas de 1 euro, b de 2 euros, c de 5 euros, d de 10 euros y e de 20 euros. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Soluciones en Haskell

El código se encuentra en GitHub.


Soluciones en Python

El código se encuentra en GitHub.

Comentarios

  • El producto de dos números x e y se escribe en Python igual que en Haskell: x * y.

Media aritmética de tres números

Definir la función

tal que (media3 x y z) es la media aritmética de los números x, y y z. Por ejemplo,

Soluciones

A continuación se muestran las soluciones en Haskell y las soluciones en Python.


Solución en Haskell

El código se encuentra en GitHub.


Soluciones en Python

El código se encuentra en GitHub.

Comentarios

  • Los comentarios irán resaltando las diferencias de la solución en Python respecto de la de Haskell (que no se hayan comentado en ningún ejercicio anterior).
  • La estructura de la definición en Python es

  • La suma de dos números x e y se escribe en Python igual que en Haskell: x + y.
  • El cociente de dos números decimales x e y se escribe en Python igual que en Haskell: x / y.

Curso de introducción a la programación con Haskell y Python

Mañana comenzará en Exercitium un curso práctico de introducción a la programación con Haskell y Python.

Diariamente, se publicará un ejercicio con sus soluciones en Haskell y en Python. El orden de los ejercicios se corresponde con el de los temas del curso de Programación funcional con Haskell. Además, en cada ejercicio se comentarán las diferencias entre ambos lenguajes y se irá extendiendo la tabla de equivalencia entre Haskell y Python.

Las soluciones de los ejercicios con Haskell se irán añadiendo al repositorio Exercitium em GitHub. Están como un proyecto con Stack (en concreto, la LTS-18.24) de forma que se puede verificar los ejemplos con

Las soluciones de los ejercicios con Python se irán añadiendo al repositorio Exercitium-Python em GitHub. Están como un proyecto con Poetry que usa la versión 3.10 de Python. También se pueden verificar los ejemplos con

He intentado escribir soluciones en Python parecidas a la de Haskell, conservando el estilo funcional. De todas formas, en los comentarios se pueden escribir definiciones alternativas en cualquiera de los lenguajes.

Los libros de Haskell en los que me he basado son

Los libros de Python en los que me he basado son

Números de Pentanacci

Los números de Fibonacci se definen mediante las ecuaciones

Los primeros números de Fibonacci son

Una generalización de los anteriores son los números de Pentanacci definidos por las siguientes ecuaciones

Los primeros números de Pentanacci son

Definir la sucesión

cuyos elementos son los números de Pentanacci. Por ejemplo,

Soluciones

El código se encuentra en GitHub.

Referencias

Número de representaciones de n como suma de dos cuadrados


Sea n un número natural cuya factorización prima es
$$n = 2^{a} \times p(1)^{b(1)} \times \dots \times p(n)^{b(n)} \times q(1)^{c(1)} \times \dots \times q(m)^{c(m)}$$
donde los p(i) son los divisores primos de n congruentes con 3 módulo 4 y los q(j) son los divisores primos de n congruentes con 1 módulo 4. Entonces, el número de forma de descomponer n como suma de dos
cuadrados es 0, si algún b(i) es impar y es el techo (es decir, el número entero más próximo por exceso) de
$$\frac{(1+c(1)) \times \dots \times (1+c(m))}{2}$$
en caso contrario. Por ejemplo, el número
$$2^{3} \times (3^{9} \times 7^{8}) \times (5^{3} \times 13^{6})$$
no se puede descomponer como sumas de dos cuadrados (porque el exponente de 3 es impar) y el número
$$2^{3} \times (3^{2} \times 7^{8}) \times (5^{3} \times 13^{6})$$
tiene 14 descomposiciones como suma de dos cuadrados (porque los exponentes de 3 y 7 son pares y el techo de
$$\frac{(1+3) \times (1+6)}{2}$$
es 14).

Definir la función

tal que (nRepresentaciones n) es el número de formas de representar n como suma de dos cuadrados. Por ejemplo,

Usando la función representaciones del ejercicio anterior, comprobar con QuickCheck la siguiente propiedad

Soluciones

El código se encuentra en GitHub.

Referencias

Representaciones de un número como suma de dos cuadrados

Definir la función

tal que (representaciones n) es la lista de pares de números naturales (x,y) tales que n = x^2 + y^2. Por ejemplo.

Comprobar con QuickCheck que un número natural n se puede como suma de dos cuadrados si, y sólo si, en la factorización prima de n todos los exponentes de sus factores primos congruentes con 3 módulo 4 son pares.

Soluciones

El código se encuentra en GitHub.

Factorizaciones de números de Hilbert

Un número de Hilbert es un entero positivo de la forma 4n+1. Los primeros números de Hilbert son 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, …

Un primo de Hilbert es un número de Hilbert n que no es por ningún número de Hilbert menor que n (salvo el 1). Los primeros primos de Hilbert son 5, 9, 13, 17, 21, 29, 33, 37, 41, 49, 53, 57, 61, 69, 73, 77, 89, 93, 97, 101, 109, 113, 121, 129, 133, 137, …

Definir la función

tal que (factorizacionesH n) es la listas de primos de Hilbert cuyo producto es el número de Hilbert n. Por ejemplo,

Comprobar con QuickCheck que todos los números de Hilbert son factorizables como producto de primos de Hilbert (aunque la factorización, como para el 441, puede no ser única).

Soluciones

El código se encuentra en GitHub.

Referencias

Basado en el artículo Failure of unique factorization (A example of the failure of the fundamental theorem of arithmetic) de R.J. Lipton en el blog Gödel’s Lost Letter and P=NP.

Otras referencias

Números primos de Hilbert

Un número de Hilbert es un positivo de la forma 4n+1. Los primeros números de Hilbert son 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, …

Un primo de Hilbert es un número de Hilbert n que no es por ningún número de Hilbert menor que n (salvo el 1). Los primeros primos de Hilbert son 5, 9, 13, 17, 21, 29, 33, 37, 41, 49, 53, 57, 61, 69, 73, 77, 89, 93, 97, 101, 109, 113, 121, 129, 133, 137, 141, 149, 157, 161, 173, 177, 181, 193, 197, …

Definir la sucesión

tal que sus elementos son los primos de Hilbert. Por ejemplo,

Soluciones

El código se encuentra en GitHub.