PFH: La semana en Exercitium (26 de agosto de 2022)
Esta semana he publicado en Exercitium las soluciones de los siguientes problemas:
- 1. Interior de una lista
- 2. Elementos finales
- 3. Segmento de una lista
- 4. Primeros y últimos elementos
- 5. Elemento mediano
A continuación se muestran las soluciones.
1. Interior de una lista
Definir la función
1 |
interior :: [a] -> [a] |
tal que (interior xs)
es la lista obtenida eliminando los extremos de la lista xs
. Por ejemplo,
1 2 |
interior [2,5,3,7,3] == [5,3,7] interior [2..7] == [3,4,5,6] |
Soluciones en Haskell
1 2 |
interior :: [a] -> [a] interior xs = tail (init xs) |
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 |
from typing import TypeVar from hypothesis import given, strategies as st A = TypeVar('A') # 1ª solución def interior1(xs: list[A]) -> list[A]: return xs[1:][:-1] # 2ª solución def interior2(xs: list[A]) -> list[A]: return xs[1:-1] # La propiedad de equivalencia es @given(st.lists(st.integers())) def test_triangular(xs): assert interior1(xs) == interior2(xs) # La comprobación es # src> poetry run pytest -q interior_de_una_lista.py # 1 passed in 0.21s |
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]
.
- en Haskell, con
2. Elementos finales
Definir la función
1 |
finales :: Int -> [a] -> [a] |
tal que (finales n xs)
es la lista formada por los n
finales elementos de xs
. Por ejemplo,
1 |
finales 3 [2,5,4,7,9,6] == [7,9,6] |
Soluciones en Haskell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import Test.QuickCheck -- 1ª definición finales1 :: Int -> [a] -> [a] finales1 n xs = drop (length xs - n) xs -- 2ª definición finales2 :: Int -> [a] -> [a] finales2 n xs = reverse (take n (reverse xs)) -- Comprobación de equivalencia -- ============================ -- La propiedad es prop_finales :: Int -> [Int] -> Bool prop_finales n xs = finales1 n xs == finales2 n xs -- La comprobación es -- λ> quickCheck prop_finales -- +++ 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 30 |
from typing import TypeVar from hypothesis import given, strategies as st A = TypeVar('A') # 1ª definición def finales1(n: int, xs: list[A]) -> list[A]: if len(xs) <= n: return xs return xs[len(xs) - n:] # 2ª definición def finales2(n: int, xs: list[A]) -> list[A]: if n == 0: return [] return xs[-n:] # 3ª definición def finales3(n: int, xs: list[A]) -> list[A]: ys = list(reversed(xs)) return list(reversed(ys[:n])) # La propiedad de equivalencia es @given(st.integers(min_value=0), st.lists(st.integers())) def test_equiv_finales(n, xs): assert finales1(n, xs) == finales2(n, xs) == finales3(n, xs) # La comprobación es # src> poetry run pytest -q elementos_finales.py # 1 passed in 0.18s |
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)
.
- en Haskell, con
3. Segmento de una lista
Definir la función
1 |
segmento :: Int -> Int -> [a] -> [a] |
tal que (segmento m n xs)
es la lista de los elementos de xs
comprendidos entre las posiciones m
y n
. Por ejemplo,
1 2 3 |
segmento 3 4 [3,4,1,2,7,9,0] == [1,2] segmento 3 5 [3,4,1,2,7,9,0] == [1,2,7] segmento 5 3 [3,4,1,2,7,9,0] == [] |
Soluciones en Haskell
1 2 |
segmento :: Int -> Int -> [a] -> [a] segmento m n xs = drop (m-1) (take n xs) |
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 |
from typing import TypeVar from hypothesis import given, strategies as st A = TypeVar('A') # 1ª definición def segmento1(m: int, n: int, xs: list[A]) -> list[A]: ys = xs[:n] return ys[m - 1:] # 2ª definición def segmento2(m: int, n: int, xs: list[A]) -> list[A]: return xs[m-1:n] # La propiedad de equivalencia es @given(st.integers(), st.integers(), st.lists(st.integers())) def test_equiv_segmento(m, n, xs): assert segmento1(m, n, xs) == segmento2(m, n, xs) # La comprobación es # src> poetry run pytest -q segmento_de_una_lista.py # 1 passed in 0.19s |
El código se encuentra en GitHub.
4. Primeros y últimos elementos
Definir la función
1 |
extremos :: Int -> [a] -> [a] |
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,
1 |
extremos 3 [2,6,7,1,2,4,5,8,9,2,3] == [2,6,7,9,2,3] |
Soluciones en Haskell
1 2 |
extremos :: Int -> [a] -> [a] extremos n xs = take n xs ++ drop (length xs - n) xs |
El código se encuentra en GitHub.
Soluciones en Python
1 2 3 4 5 6 |
from typing import TypeVar A = TypeVar('A') def extremos(n: int, xs: list[A]) -> list[A]: return xs[:n] + xs[-n:] |
El código se encuentra en GitHub.
5. Elemento mediano
Definir la función
1 |
mediano :: Int -> Int -> Int -> Int |
tal que (mediano x y z)
es el número mediano de los tres números x
, y
y z
. Por ejemplo,
1 2 3 4 |
mediano 3 2 5 == 3 mediano 2 4 5 == 4 mediano 2 6 5 == 5 mediano 2 6 6 == 6 |
Soluciones en Haskell
1 2 |
mediano :: Int -> Int -> Int -> Int mediano x y z = x + y + z - minimum [x,y,z] - maximum [x,y,z] |
El código se encuentra en GitHub.
Soluciones en Python
1 2 |
def mediano(x: int, y: int, z: int) -> int: return x + y + z - min([x, y, z]) - max([x, y, z]) |
El código se encuentra en GitHub.