Se consideran el tipo de las posiciones del plano definido por
type Posicion = (Int,Int)
<7p
y el tipo de las direcciones definido por
<pre lang="text">
data Direccion = Izquierda | Derecha | Arriba | Abajo
deriving Show |
type Posicion = (Int,Int)
<7p
y el tipo de las direcciones definido por
<pre lang="text">
data Direccion = Izquierda | Derecha | Arriba | Abajo
deriving Show
Definir las siguientes funciones
opuesta :: Direccion -> Direccion
movimiento :: Posicion -> Direccion -> Posicion
movimientos :: Posicion -> [Direccion] -> Posicion |
opuesta :: Direccion -> Direccion
movimiento :: Posicion -> Direccion -> Posicion
movimientos :: Posicion -> [Direccion] -> Posicion
tales que
opuesta d
es la dirección opuesta de d
. Por ejemplo,
opuesta Izquierda == Derecha |
opuesta Izquierda == Derecha
movimiento p d
es la posición reultante de moverse, desde la posición p
, un paso en la dirección d
. Por ejemplo,
movimiento (2,5) Arriba == (2,6)
movimiento (2,5) (opuesta Abajo) == (2,6) |
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 de ds
a la posición p
. Por ejemplo,
movimientos (2,5) [Arriba, Izquierda] == (1,6) |
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 |
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) |
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)