Movimientos en el plano
Se consideran el tipo de las posiciones del plano definido por
type Posicion = (Int,Int)
y el tipo de las direcciones definido por
data Direccion = Izquierda | Derecha | Arriba | Abajo deriving Show
Definir las siguientes funciones
opuesta :: Direccion -> Direccion movimiento :: Posicion -> Direccion -> Posicion movimientos :: Posicion -> [Direccion] -> Posicion
tales que
-
opuesta d
es la dirección opuesta ded
. Por ejemplo,
opuesta Izquierda == Derecha
-
movimiento p d
es la posición reultante de moverse, desde la posiciónp
, un paso en la direcciónd
. Por ejemplo,
movimiento (2,5) Arriba == (2,6) movimiento (2,5) (opuesta Abajo) == (2,6)
-
movimientos p ds
es la posición obtenida aplicando la lista de movimientos según las direcciones deds
a la posiciónp
. Por ejemplo,
movimientos (2,5) [Arriba, Izquierda] == (1,6)
Soluciones
A continuación se muestran las soluciones en Haskell y las soluciones en Python.
Soluciones en Haskell
type Posicion = (Int,Int) data Direccion = Izquierda | Derecha | Arriba | Abajo deriving Show -- Definición de opuesta -- ===================== opuesta :: Direccion -> Direccion opuesta Izquierda = Derecha opuesta Derecha = Izquierda opuesta Arriba = Abajo opuesta Abajo = Arriba -- 1ª definición de movimiento -- =========================== movimiento1 :: Posicion -> Direccion -> Posicion movimiento1 (x,y) Izquierda = (x-1,y) movimiento1 (x,y) Derecha = (x+1,y) movimiento1 (x,y) Arriba = (x,y+1) movimiento1 (x,y) Abajo = (x,y-1) -- 2ª definición de movimiento -- =========================== movimiento2 :: Posicion -> Direccion -> Posicion movimiento2 (x,y) d = case d of Izquierda -> (x-1,y) Derecha -> (x+1,y) Arriba -> (x,y+1) Abajo -> (x,y-1) -- 1ª definición de movimientos -- ============================ movimientos1 :: Posicion -> [Direccion] -> Posicion movimientos1 p [] = p movimientos1 p (d:ds) = movimientos1 (movimiento1 p d) ds -- 2ª definición de movimientos -- ============================ movimientos2 :: Posicion -> [Direccion] -> Posicion movimientos2 = foldl movimiento1
Soluciones en Python
from enum import Enum from functools import reduce Posicion = tuple[int, int] Direccion = Enum('Direccion', ['Izquierda', 'Derecha', 'Arriba', 'Abajo']) # 1ª definición de opuesta # ======================== def opuesta1(d: Direccion) -> Direccion: if d == Direccion.Izquierda: return Direccion.Derecha if d == Direccion.Derecha: return Direccion.Izquierda if d == Direccion.Arriba: return Direccion.Abajo if d == Direccion.Abajo: return Direccion.Arriba assert False # 2ª definición de opuesta # ======================== def opuesta2(d: Direccion) -> Direccion: match d: case Direccion.Izquierda: return Direccion.Derecha case Direccion.Derecha: return Direccion.Izquierda case Direccion.Arriba: return Direccion.Abajo case Direccion.Abajo: return Direccion.Arriba assert False # 1ª definición de movimiento # =========================== def movimiento1(p: Posicion, d: Direccion) -> Posicion: (x, y) = p if d == Direccion.Izquierda: return (x - 1, y) if d == Direccion.Derecha: return (x + 1, y) if d == Direccion.Arriba: return (x, y + 1) if d == Direccion.Abajo: return (x, y - 1) assert False # 2ª definición de movimiento # =========================== def movimiento2(p: Posicion, d: Direccion) -> Posicion: (x, y) = p match d: case Direccion.Izquierda: return (x - 1, y) case Direccion.Derecha: return (x + 1, y) case Direccion.Arriba: return (x, y + 1) case Direccion.Abajo: return (x, y - 1) assert False # 1ª definición de movimientos # ============================ def movimientos1(p: Posicion, ds: list[Direccion]) -> Posicion: if not ds: return p return movimientos1(movimiento1(p, ds[0]), ds[1:]) # 2ª definición de movimientos # ============================ def movimientos2(p: Posicion, ds: list[Direccion]) -> Posicion: return reduce(movimiento1, ds, p)