Menu Close

Día: 23 noviembre, 2022

Movimientos en el plano

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

Definir las siguientes funciones

   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
  • 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)
  • 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)

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)