{"id":7531,"date":"2022-11-23T06:00:26","date_gmt":"2022-11-23T04:00:26","guid":{"rendered":"http:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=7531"},"modified":"2022-12-14T11:34:55","modified_gmt":"2022-12-14T09:34:55","slug":"23-nov-22","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/23-nov-22\/","title":{"rendered":"Movimientos en el plano"},"content":{"rendered":"<p>Se consideran el tipo de las posiciones del plano definido por<\/p>\n<pre lang=\"text\">\n   type Posicion = (Int,Int)\n   <7p\ny el tipo de las direcciones definido por\n<pre lang=\"text\">\n   data Direccion = Izquierda | Derecha | Arriba | Abajo\n     deriving Show\n<\/pre>\n<p>Definir las siguientes funciones<\/p>\n<pre lang=\"text\">\n   opuesta     :: Direccion -> Direccion\n   movimiento  :: Posicion -> Direccion -> Posicion\n   movimientos :: Posicion -> [Direccion] -> Posicion\n<\/pre>\n<p>tales que<\/p>\n<ul>\n<li><code>opuesta d<\/code> es la direcci\u00f3n opuesta de <code>d<\/code>. Por ejemplo,<\/li>\n<\/ul>\n<pre lang=\"text\">\n     opuesta Izquierda == Derecha\n<\/pre>\n<ul>\n<li><code>movimiento p d<\/code> es la posici\u00f3n reultante de moverse, desde la  posici\u00f3n <code>p<\/code>, un paso en la direcci\u00f3n <code>d<\/code>. Por ejemplo,<\/li>\n<\/ul>\n<pre lang=\"text\">\n     movimiento (2,5) Arriba          == (2,6)\n     movimiento (2,5) (opuesta Abajo) == (2,6)\n<\/pre>\n<ul>\n<li><code>movimientos p ds<\/code> es la posici\u00f3n obtenida aplicando la lista de movimientos seg\u00fan las direcciones de <code>ds<\/code> a la posici\u00f3n <code>p<\/code>. Por ejemplo,<\/li>\n<\/ul>\n<pre lang=\"text\">\n     movimientos (2,5)  [Arriba, Izquierda] == (1,6)\n<\/pre>\n<p><b>Soluciones<\/b><\/p>\n<p>A continuaci\u00f3n se muestran las <a href=\"#haskell\">soluciones en Haskell<\/a> y las <a href=\"#python\">soluciones en Python<\/a>.<\/p>\n<p><a name=\"haskell\"><\/a><br \/>\n<b>Soluciones en Haskell<\/b><\/p>\n<pre lang=\"haskell\">\ntype Posicion = (Int,Int)\n\ndata Direccion = Izquierda | Derecha | Arriba | Abajo\n  deriving Show\n\n-- Definici\u00f3n de opuesta\n-- =====================\n\nopuesta :: Direccion -> Direccion\nopuesta Izquierda = Derecha\nopuesta Derecha   = Izquierda\nopuesta Arriba    = Abajo\nopuesta Abajo     = Arriba\n\n-- 1\u00aa definici\u00f3n de movimiento\n-- ===========================\n\nmovimiento1 :: Posicion -> Direccion -> Posicion\nmovimiento1 (x,y) Izquierda = (x-1,y)\nmovimiento1 (x,y) Derecha   = (x+1,y)\nmovimiento1 (x,y) Arriba    = (x,y+1)\nmovimiento1 (x,y) Abajo     = (x,y-1)\n\n-- 2\u00aa definici\u00f3n de movimiento\n-- ===========================\n\nmovimiento2 :: Posicion -> Direccion -> Posicion\nmovimiento2 (x,y) d =\n  case d of\n    Izquierda -> (x-1,y)\n    Derecha   -> (x+1,y)\n    Arriba    -> (x,y+1)\n    Abajo     -> (x,y-1)\n\n-- 1\u00aa definici\u00f3n de movimientos\n-- ============================\n\nmovimientos1 :: Posicion -> [Direccion] -> Posicion\nmovimientos1 p []     = p\nmovimientos1 p (d:ds) = movimientos1 (movimiento1 p d) ds\n\n-- 2\u00aa definici\u00f3n de movimientos\n-- ============================\n\nmovimientos2 :: Posicion -> [Direccion] -> Posicion\nmovimientos2 = foldl movimiento1\n<\/pre>\n<p><a name=\"python\"><\/a><br \/>\n<b>Soluciones en Python<\/b><\/p>\n<pre lang=\"python\">\nfrom enum import Enum\nfrom functools import reduce\n\nPosicion = tuple[int, int]\n\nDireccion = Enum('Direccion', ['Izquierda', 'Derecha', 'Arriba', 'Abajo'])\n\n# 1\u00aa definici\u00f3n de opuesta\n# ========================\n\ndef opuesta1(d: Direccion) -> Direccion:\n    if d == Direccion.Izquierda:\n        return Direccion.Derecha\n    if d == Direccion.Derecha:\n        return Direccion.Izquierda\n    if d == Direccion.Arriba:\n        return Direccion.Abajo\n    if d == Direccion.Abajo:\n        return Direccion.Arriba\n    assert False\n\n# 2\u00aa definici\u00f3n de opuesta\n# ========================\n\ndef opuesta2(d: Direccion) -> Direccion:\n    match d:\n        case Direccion.Izquierda:\n            return Direccion.Derecha\n        case Direccion.Derecha:\n            return Direccion.Izquierda\n        case Direccion.Arriba:\n            return Direccion.Abajo\n        case Direccion.Abajo:\n            return Direccion.Arriba\n    assert False\n\n# 1\u00aa definici\u00f3n de movimiento\n# ===========================\n\ndef movimiento1(p: Posicion, d: Direccion) -> Posicion:\n    (x, y) = p\n    if d == Direccion.Izquierda:\n        return (x - 1, y)\n    if d == Direccion.Derecha:\n        return (x + 1, y)\n    if d == Direccion.Arriba:\n        return (x, y + 1)\n    if d == Direccion.Abajo:\n        return (x, y - 1)\n    assert False\n\n# 2\u00aa definici\u00f3n de movimiento\n# ===========================\n\ndef movimiento2(p: Posicion, d: Direccion) -> Posicion:\n    (x, y) = p\n    match d:\n        case Direccion.Izquierda:\n            return (x - 1, y)\n        case Direccion.Derecha:\n            return (x + 1, y)\n        case Direccion.Arriba:\n            return (x, y + 1)\n        case Direccion.Abajo:\n            return (x, y - 1)\n    assert False\n\n# 1\u00aa definici\u00f3n de movimientos\n# ============================\n\ndef movimientos1(p: Posicion, ds: list[Direccion]) -> Posicion:\n    if not ds:\n        return p\n    return movimientos1(movimiento1(p, ds[0]), ds[1:])\n\n# 2\u00aa definici\u00f3n de movimientos\n# ============================\n\ndef movimientos2(p: Posicion, ds: list[Direccion]) -> Posicion:\n    return reduce(movimiento1, ds, p)\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Se consideran el tipo de las posiciones del plano definido por type Posicion = (Int,Int) Direccion movimiento :: Posicion -> Direccion -> Posicion movimientos :: Posicion -> [Direccion] -> Posicion tales que opuesta d es la direcci\u00f3n opuesta de d. Por ejemplo, opuesta Izquierda == Derecha movimiento p d es la posici\u00f3n reultante de moverse,&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"footnotes":"","_jetpack_memberships_contains_paid_content":false},"categories":[581],"tags":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/7531"}],"collection":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/comments?post=7531"}],"version-history":[{"count":4,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/7531\/revisions"}],"predecessor-version":[{"id":7642,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/7531\/revisions\/7642"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=7531"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=7531"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=7531"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}