PFH: La semana en Exercitium (19 de agosto de 2022)
Esta semana he publicado en Exercitium las soluciones de los siguientes problemas:
- 1. Máximo de tres números
- 2. El primero al final
- 3. Los primeros al final
- 4. Rango de una lista
- 5. Reconocimiento de palíndromos
A continuación se muestran las soluciones.
1. Máximo de tres números
Definir la función
1 |
maxTres :: Int -> Int -> Int -> Int |
tal que (maxTres x y z)
es el máximo de x
, y
y z
. Por ejemplo,
1 2 3 |
maxTres 6 2 4 == 6 maxTres 6 7 4 == 7 maxTres 6 7 9 == 9 |
Solución en Haskell
1 2 |
maxTres :: Int -> Int -> Int -> Int maxTres x y z = max x (max y z) |
El código se encuentra en GitHub.
Soluciones en Python
1 2 3 |
def maxTres(x, y, z): # type: (int, int, int) -> int return max(x, max(y, z)) |
El código se encuentra en GitHub.
Comentarios
- El máximo de
x
ey
se escribe- en Haskell,
max x y
y - en Python,
max(x, y)
.
- en Haskell,
2. El primero al final
Definir la función
1 |
rota1 :: [a] -> [a] |
tal que (rota1 xs)
es la lista obtenida poniendo el primer elemento de xs
al final de la lista. Por ejemplo,
1 |
rota1 [3,2,5,7] == [2,5,7,3] |
Soluciones en Haskell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import Test.QuickCheck -- 1ª solución -- =========== rota1a :: [a] -> [a] rota1a [] = [] rota1a xs = tail xs ++ [head xs] -- 2ª solución -- =========== rota1b :: [a] -> [a] rota1b [] = [] rota1b (x:xs) = xs ++ [x] -- Comprobación de equivalencia -- ============================ -- La propiedad es prop_rota1 :: [Int] -> Bool prop_rota1 xs = rota1a xs == rota1b xs -- La comprobación es -- λ> quickCheck prop_rota1 -- +++ OK, passed 100 tests. |
El código se encuentra en GitHub.
Soluciones en Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
from typing import List, TypeVar from hypothesis import given, strategies as st A = TypeVar('A') # 1ª solución def rota1a(xs): # type: (List[A]) -> List[A] if xs == []: return [] return xs[1:] + [xs[0]] # 2ª solución def rota1b(xs): # type: (List[A]) -> List[A] if xs == []: return [] ys = xs[1:] ys.append(xs[0]) return ys # La equivalencia de las definiciones es @given(st.lists(st.integers())) def test_rota1(xs): assert rota1a(xs) == rota1b(xs) # La comprobación es # src> poetry run pytest -q el_primero_al_final.py # 1 passed in 0.20s |
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]
- en Haskell, con
- El resto de la lista
xs
se calcula- en Haskell, con
tail xs
- en Python, con
xs[1:]
- en Haskell, con
- La concatenación de las listas
xs
eys
se calcula- en Haskell, con
xs ++ ys
- en Python, con
xs + ys
- en Haskell, con
- En Python.
xs.append(x)
modifica la listaxs
añadiéndolex
al final. Por ejemplo,
1 2 3 4 |
>>> xs = [3, 2, 5] >>> xs.append(1) >>> xs [3, 2, 5, 1] |
3. Los primeros al final
Definir la función
1 |
rota :: Int -> [a] -> [a] |
tal que (rota n xs)
es la lista obtenida poniendo los n
primeros elementos de xs
al final de la lista. Por ejemplo,
1 2 3 |
rota 1 [3,2,5,7] == [2,5,7,3] rota 2 [3,2,5,7] == [5,7,3,2] rota 3 [3,2,5,7] == [7,3,2,5] |
Soluciones en Haskell
1 2 |
rota :: Int -> [a] -> [a] rota n xs = drop n xs ++ take n xs |
El código se encuentra en GitHub.
Soluciones en Python
1 2 3 4 5 6 7 |
from typing import List, TypeVar A = TypeVar('A') def rota(n, xs): # type: (int, List[A]) -> List[A] return xs[n:] + xs[:n] |
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]
.
4. Rango de una lista
Definir la función
1 |
rango :: [Int] -> [Int] |
tal que (rango xs)
es la lista formada por el menor y mayor elemento de xs
. Por ejemplo,
1 |
rango [3,2,7,5] == [2,7] |
Soluciones en Haskell
1 2 |
rango :: [Int] -> [Int] rango xs = [minimum xs, maximum xs] |
El código se encuentra en GitHub.
Soluciones en Python
1 2 3 4 5 |
from typing import List def rango(xs): # type: (List[int]) -> List[int] return [min(xs), max(xs)] |
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)
.
- en Haskell, con
- El mayor elemento de la lista
xs
se calcula- en Haskell, con
maximum xs
y - en Python, con
max(xs)
.
- en Haskell, con
5. Reconocimiento de palíndromos
Definir la función
1 |
palindromo :: Eq a => [a] -> Bool |
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,
1 2 |
palindromo [3,2,5,2,3] == True palindromo [3,2,5,6,2,3] == False |
Soluciones en Haskell
1 2 3 |
palindromo :: Eq a => [a] -> Bool palindromo xs = xs == reverse xs |
El código se encuentra en GitHub.
Soluciones en Python
1 2 3 4 5 6 7 |
from typing import List, TypeVar A = TypeVar('A') def palindromo(xs): # type: (List[A]) -> bool return xs == list(reversed(xs)) |
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))
.
- en Haskell, con
- Para comparar la igualdad de dos listas
xs
eys
se escribe igual qh Haskell y en Python:xs == ys
.