Menu Close

Mes: agosto 2022

División segura

Definir la función

   divisionSegura :: Double -> Double -> Double

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

   divisionSegura 7 2  ==  3.5
   divisionSegura 7 0  ==  9999.0

Soluciones

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


Soluciones en Haskell

import Test.QuickCheck
 
-- 1ª definición
divisionSegura1 :: Double -> Double -> Double
divisionSegura1 x y =
  if y == 0 then 9999 else x/y
 
-- 2ª definición
divisionSegura2 :: Double -> Double -> Double
divisionSegura2 _ 0 = 9999
divisionSegura2 x y = x/y
 
-- Comprobación de equivalencia
-- ============================
 
-- La propiedad es
prop_divisionSegura :: Double -> Double -> Bool
prop_divisionSegura x y =
  divisionSegura1 x y == divisionSegura2 x y
 
-- La comprobación es
--    λ> quickCheck prop_divisionSegura
--    +++ OK, passed 100 tests.

El código se encuentra en GitHub.


Soluciones en Python

from hypothesis import given, strategies as st
 
# 1ª definición
def divisionSegura1(x: float, y: float) -> float:
    if y == 0:
        return 9999.0
    return x/y
 
# 2ª definición
def divisionSegura2(x: float, y: float) -> float:
    match y:
        case 0:
            return 9999.0
        case _:
            return x/y
 
# La propiedad de equivalencia es
@given(st.floats(allow_nan=False, allow_infinity=False),
       st.floats(allow_nan=False, allow_infinity=False))
def test_equiv_divisionSegura(x, y):
    assert divisionSegura1(x, y) == divisionSegura2(x, y)
 
# La comprobación es
#    src> poetry run pytest -q division_segura.py
#    1 passed in 0.37s

El código se encuentra en GitHub.

Comentarios

  • El condicional se escribe en Haskell como
if <condición> then <valor1> else <valor2>

y en Python como

if <condición>:
    return <valor1>
return <valor2>
  • 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

   tresDiferentes :: Int -> Int -> Int -> Bool

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

   tresDiferentes 3 5 2  ==  True
   tresDiferentes 3 5 3  ==  False

Soluciones

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


Soluciones en Haskell

tresDiferentes :: Int -> Int -> Int -> Bool
tresDiferentes x y z = x /= y && x /= z && y /= z

El código se encuentra en GitHub.


Soluciones en Python

def tresDiferentes(x: int, y: int, z: int) -> bool:
    return x != y and x != z and y != z

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

   tresIguales :: Int -> Int -> Int -> Bool

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

   tresIguales 4 4 4  ==  True
   tresIguales 4 3 4  ==  False

Soluciones

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


Soluciones en Haskell

tresIguales :: Int -> Int -> Int -> Bool
tresIguales x y z = x == y && y == z

El código se encuentra en GitHub.


Soluciones en Python

from hypothesis import given, strategies as st
 
# 1ª definición
def tresIguales1(x: int, y: int, z: int) -> bool:
    return x == y and y == z
 
# 2ª definición
def tresIguales2(x: int, y: int, z: int) -> bool:
    return x == y == z
 
# La propiedad de equivalencia es
@given(st.integers(), st.integers(), st.integers())
def test_equiv_tresIguales(x, y, z):
    assert tresIguales1(x, y, z) == tresIguales2(x, y, z)
 
# La comprobación es
#    src> poetry run pytest -q tres_iguales.py
#    1 passed in 0.16s

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

   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,

   mediano 3 2 5  ==  3
   mediano 2 4 5  ==  4
   mediano 2 6 5  ==  5
   mediano 2 6 6  ==  6

Soluciones

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


Soluciones en Haskell

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

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.

Primeros y últimos elementos

Definir la función

   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,

   extremos 3 [2,6,7,1,2,4,5,8,9,2,3]  ==  [2,6,7,9,2,3]

Soluciones

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


Soluciones en Haskell

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

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.