{"id":8267,"date":"2023-08-19T06:00:25","date_gmt":"2023-08-19T04:00:25","guid":{"rendered":"http:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=8267"},"modified":"2023-08-05T17:29:27","modified_gmt":"2023-08-05T15:29:27","slug":"19-ago-23","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/19-ago-23\/","title":{"rendered":"El problema de las fichas mediante b\u00fasqueda en espacio de estado"},"content":{"rendered":"<p>Para el problema de las fichas de orden (m,n) se considera un tablero con m+n+1 cuadrados consecutivos.<\/p>\n<p>Inicialmente, en cada uno de los m primeros cuadrados hay una  blanca, a continuaci\u00f3n un hueco y  en cada uno de los n \u00faltimos cuadrados hay una ficha verde. El objetivo consiste en tener las fichas verdes al principio y las blancas al final.<\/p>\n<p>Por ejemplo, en el problema de las fichas de orden (3,3) el tablero inicial es<\/p>\n<pre lang=\"text\">\n      +---+---+---+---+---+---+---+\n      | B | B | B |   | V | V | V |\n      +---+---+---+---+---+---+---+\n<\/pre>\n<p>y el final es<\/p>\n<pre lang=\"text\">\n      +---+---+---+---+---+---+---+\n      | V | V | V |   | B | B | B |\n      +---+---+---+---+---+---+---+\n<\/pre>\n<p>Los movimientos permitidos consisten en desplazar una ficha al hueco saltando, como m\u00e1ximo, sobre otras dos.<\/p>\n<p>Para representar el problema se definen los siguientes tipos de datos:<\/p>\n<ul>\n<li><code>Ficha<\/code> con tres constructores <code>B<\/code>, <code>V<\/code> y <code>H<\/code> que representan las fichas blanca, verde y hueco, respectivamente.<\/li>\n<\/ul>\n<pre lang=\"text\">\n     data Ficha = B | V | H\n       deriving (Eq, Show)\n<\/pre>\n<ul>\n<li><code>Tablero<\/code> que es una lista de fichas que representa las fichas colocadas en el tablero.<\/li>\n<\/ul>\n<pre lang=\"text\">\n     type Tablero = [Ficha]\n<\/pre>\n<ul>\n<li><code>Estado<\/code> representa los estados del espacio de b\u00fasqueda, donde un estado es una lista de tableros [t(n), &#8230;, t(2), t(1)] tal que t(1) es el tablero inicial y para cada i (2 &lt;= i &lt;= n), t(i) es un sucesor de t(i-1).<\/li>\n<\/ul>\n<pre lang=\"text\">\n     newtype Estado = E [Tablero]\n       deriving (Eq, Show)\n<\/pre>\n<ul>\n<li><code>Busqueda<\/code> es un procedimiento de b\u00fasqueda<\/li>\n<\/ul>\n<pre lang=\"text\">\n     type Busqueda = (Estado -> [Estado]) ->\n                     (Estado -> Bool) ->\n                     Estado ->\n                     [Estado]\n<\/pre>\n<p>Adem\u00e1s, se considera la heur\u00edstica que para cada tablero vale la suma de piezas blancas situadas a la izquierda de cada una de las piezas verdes. Por  ejemplo, para el estado<\/p>\n<pre lang=\"text\">\n      +---+---+---+---+---+---+---+\n      | B | V | B |   | V | V | B |\n      +---+---+---+---+---+---+---+\n<\/pre>\n<p>su valor es 1+2+2 = 5. La heur\u00edstica de un estado es la del primero de sus tableros.<\/p>\n<p>Usando los m\u00e9todos de b\u00fasqueda estudiado en los ejercicios anteriores, definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   fichas :: Busqueda -> Int -> Int -> [[Tablero]]\n<\/pre>\n<p>tal que <code>fichas b m n<\/code> es la lista de las soluciones del problema de las fichas de orden (m,n) obtenidas mediante el procedimiento de b\u00fasqueda b. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   \u03bb> head (fichas buscaProfundidad 2 2)\n   [[B,B,H,V,V],[B,H,B,V,V],[H,B,B,V,V],[V,B,B,H,V],[V,B,H,B,V],[V,H,B,B,V],\n    [H,V,B,B,V],[B,V,H,B,V],[B,H,V,B,V],[H,B,V,B,V],[B,B,V,H,V],[B,B,V,V,H],\n    [B,H,V,V,B],[H,B,V,V,B],[V,B,H,V,B],[V,H,B,V,B],[H,V,B,V,B],[B,V,H,V,B],\n    [B,V,V,H,B],[H,V,V,B,B],[V,H,V,B,B],[V,V,H,B,B]]\n   \u03bb> head (fichas buscaAnchura 2 2)\n   [[B,B,H,V,V],[B,B,V,V,H],[B,H,V,V,B],[B,V,V,H,B],[H,V,V,B,B],\n    [V,V,H,B,B]]\n   \u03bb> head (fichas buscaPM 2 2)\n   [[B,B,H,V,V],[B,H,B,V,V],[B,V,B,H,V],[H,V,B,B,V],[V,H,B,B,V],\n    [V,V,B,B,H],[V,V,B,H,B],[V,V,H,B,B]]\n   \u03bb> head (fichas buscaEscalada 2 2)\n   [[B,B,H,V,V],[B,H,B,V,V],[B,V,B,H,V],[H,V,B,B,V],[V,H,B,B,V],\n    [V,V,B,B,H],[V,V,B,H,B],[V,V,H,B,B]]\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\">\nmodule BEE_El_problema_de_las_fichas where\n\nimport BusquedaEnProfundidad (buscaProfundidad)\nimport BusquedaEnAnchura (buscaAnchura)\nimport BusquedaPrimeroElMejor (buscaPM)\nimport BusquedaEnEscalada (buscaEscalada)\nimport Test.Hspec (Spec, hspec, it, shouldBe)\n\n-- Representaci\u00f3n del problema\n-- ===========================\n\ndata Ficha = B | V | H\n  deriving (Eq, Show)\n\ntype Tablero = [Ficha]\n\n-- (tableroInicial m n) representa el tablero inicial del problema de las fichas\n-- de orden (m,n). Por ejemplo,\n--    tableroInicial 2 3  ==  [B,B,H,V,V,V]\n--    tableroInicial 3 2  ==  [B,B,B,H,V,V]\ntableroInicial ::  Int -> Int -> Tablero\ntableroInicial m n = replicate m B ++ [H] ++ replicate n V\n\n-- (tableroFinal m n) representa el tablero final del problema de las fichas de\n-- orden (m,n). Por ejemplo,\n--    tableroFinal 2 3  ==  [V,V,V,H,B,B]\n--    tableroFinal 3 2  ==  [V,V,H,B,B,B]\ntableroFinal ::  Int -> Int -> Tablero\ntableroFinal m n = replicate n V ++ [H] ++ replicate m B\n\n-- (tablerosSucesores t) es la lista de los sucesores del tablero t. Por\n-- ejemplo,\n--    \u03bb> tablerosSucesores [V,B,H,V,V,B]\n--    [[V,H,B,V,V,B],[H,B,V,V,V,B],[V,B,V,H,V,B],[V,B,V,V,H,B],\n--     [V,B,B,V,V,H]]\n--    \u03bb> tablerosSucesores [B,B,B,H,V,V,V]\n--    [[B,B,H,B,V,V,V],[B,H,B,B,V,V,V],[H,B,B,B,V,V,V],\n--     [B,B,B,V,H,V,V],[B,B,B,V,V,H,V],[B,B,B,V,V,V,H]]\ntablerosSucesores :: Tablero -> [Tablero]\ntablerosSucesores t =\n  [intercambia i j t | i <- [j-1,j-2,j-3,j+1,j+2,j+3]\n                     , 0 <= i, i < n]\n  where j = posicionHueco t\n        n = length t\n\n-- (posicionHueco t) es la posici\u00f3n del hueco en el tablero t. Por\n-- ejemplo,\n--    posicionHueco (tableroInicial 3 2)  ==  3\nposicionHueco :: Tablero -> Int\nposicionHueco t = length (takeWhile (\/=H) t)\n\n-- (intercambia xs i j) es la lista obtenida intercambiando los\n-- elementos de xs en las posiciones i y j. Por ejemplo,\n--    intercambia 2 6 [0..9]  ==  [0,1,6,3,4,5,2,7,8,9]\n--    intercambia 6 2 [0..9]  ==  [0,1,6,3,4,5,2,7,8,9]\nintercambia :: Int -> Int -> [a] -> [a]\nintercambia i j xs = concat [xs1,[x2],xs2,[x1],xs3]\n  where (xs1,x1,xs2,x2,xs3) = divide (min i j) (max i j) xs\n\n-- (divide xs i j) es la tupla (xs1,x1,xs2,x2,xs3) tal que xs1 son los\n-- elementos de xs cuya posici\u00f3n es menor que i, x1 es el elemento de xs\n-- en la posici\u00f3n i, xs2 son los elementos de xs cuya posici\u00f3n es mayor\n-- que i y menor que j, x2 es el elemento de xs en la posici\u00f3n j y xs3\n-- son los elementos de xs cuya posici\u00f3n es mayor que j (suponiendo que\n-- i < j). Por ejemplo,\n--    divide 2 6 [0..9]  ==  ([0,1],2,[3,4,5],6,[7,8,9])\ndivide :: Int -> Int -> [a] -> ([a],a,[a],a,[a])\ndivide i j xs = (xs1,x1,xs2,x2,xs3)\n  where (xs1,x1:ys)  = splitAt i xs\n        (xs2,x2:xs3) = splitAt (j - i - 1) ys\n\nnewtype Estado = E [Tablero]\n  deriving (Eq, Show)\n\n-- (inicial m n) representa el estado inicial del problema de las fichas\n-- de orden (m,n). Por ejemplo,\n--    inicial 2 3  ==  E [[B,B,H,V,V,V]]\n--    inicial 3 2  ==  E [[B,B,B,H,V,V]]\ninicial :: Int -> Int -> Estado\ninicial m n = E [tableroInicial m n]\n\n-- (esFinal m n e) se verifica si e es un estado final del problema de las\n-- fichas de orden (m,n). Por ejemplo,\n--    \u03bb> esFinal 2 1 (E [[V,H,B,B],[V,B,B,H],[H,B,B,V],[B,B,H,V]])\n--    True\n--    \u03bb> esFinal 2 1 (E [[V,B,B,H],[H,B,B,V],[B,B,H,V]])\n--    False\nesFinal :: Int -> Int -> Estado -> Bool\nesFinal m n (E (e:_)) = e == tableroFinal m n\n\n-- (sucesores n) es la lista de los sucesores del estado n. Por ejemplo,\n--    \u03bb> sucesores (E [[H,B,B,V],[B,B,H,V]])\n--    [E [[B,H,B,V],[H,B,B,V],[B,B,H,V]],\n--     E [[V,B,B,H],[H,B,B,V],[B,B,H,V]]]\n--    \u03bb> sucesores (E [[B,H,B,V],[H,B,B,V],[B,B,H,V]])\n--    [E [[B,V,B,H],[B,H,B,V],[H,B,B,V],[B,B,H,V]]]\nsucesores :: Estado -> [Estado]\nsucesores (E e@(t:ts)) =\n  [E (t':e) | t' <- tablerosSucesores t,\n              t' `notElem` ts]\n\n-- Heur\u00edstica\n-- ==========\n\n-- (heuristicaT t) es la heur\u00edstica del tablero t. Por ejemplo,\n--    heuristicaT [B,V,B,H,V,V,B] == 5\nheuristicaT :: Tablero -> Int\nheuristicaT []     = 0\nheuristicaT (V:xs) = heuristicaT xs\nheuristicaT (H:xs) = heuristicaT xs\nheuristicaT (B:xs) = heuristicaT xs + length (filter (==V) xs)\n\n-- (heuristica e) es la heur\u00edstica del primer tablero del estado e. Por\n-- ejemplo,\n--    heuristica (E [[H,B,B,V],[B,B,H,V]])            ==  2\n--    heuristica (E [[V,B,B,H],[H,B,B,V],[B,B,H,V]])  ==  0\nheuristica :: Estado -> Int\nheuristica (E (t:_)) = heuristicaT t\n\n-- Estado es un subtipo de Ord de forma que un estado es menor o igual\n-- que otro si su heur\u00edstica lo es.\ninstance Ord Estado where\n  e1 <= e2 = heuristica e1 <= heuristica e2\n\n-- Soluci\u00f3n por b\u00fasqueda\n-- =====================\n\ntype Busqueda = (Estado -> [Estado]) ->\n                (Estado -> Bool) ->\n                Estado ->\n                [Estado]\n\nfichas :: Busqueda -> Int -> Int -> [[Tablero]]\nfichas b m n =\n  [reverse es | E es <- b sucesores (esFinal m n) (inicial m n)]\n\n-- Verificaci\u00f3n\n-- ============\n\nverifica :: IO ()\nverifica = hspec spec\n\nspec :: Spec\nspec = do\n  it \"e1\" $\n    head (fichas buscaProfundidad 2 2) `shouldBe`\n    [[B,B,H,V,V],[B,H,B,V,V],[H,B,B,V,V],[V,B,B,H,V],[V,B,H,B,V],[V,H,B,B,V],\n     [H,V,B,B,V],[B,V,H,B,V],[B,H,V,B,V],[H,B,V,B,V],[B,B,V,H,V],[B,B,V,V,H],\n     [B,H,V,V,B],[H,B,V,V,B],[V,B,H,V,B],[V,H,B,V,B],[H,V,B,V,B],[B,V,H,V,B],\n     [B,V,V,H,B],[H,V,V,B,B],[V,H,V,B,B],[V,V,H,B,B]]\n  it \"e2\" $\n    head (fichas buscaAnchura 2 2) `shouldBe`\n    [[B,B,H,V,V],[B,B,V,V,H],[B,H,V,V,B],[B,V,V,H,B],[H,V,V,B,B],[V,V,H,B,B]]\n  it \"e3\" $\n    head (fichas buscaPM 2 2) `shouldBe`\n    [[B,B,H,V,V],[B,H,B,V,V],[B,V,B,H,V],[H,V,B,B,V],[V,H,B,B,V],[V,V,B,B,H],\n     [V,V,B,H,B],[V,V,H,B,B]]\n  it \"e4\" $\n    head (fichas buscaEscalada 2 2) `shouldBe`\n    [[B,B,H,V,V],[B,H,B,V,V],[B,V,B,H,V],[H,V,B,B,V],[V,H,B,B,V],[V,V,B,B,H],\n     [V,V,B,H,B],[V,V,H,B,B]]\n\n-- La verificaci\u00f3n es\n--    \u03bb> verifica\n--\n--    e1\n--    e2\n--    e3\n--    e4\n--\n--    Finished in 0.0055 seconds\n--    4 examples, 0 failures\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 partial\nfrom typing import Callable, Optional\n\nfrom src.BusquedaEnAnchura import buscaAnchura1\nfrom src.BusquedaEnEscalada import buscaEscalada\nfrom src.BusquedaEnProfundidad import buscaProfundidad1\nfrom src.BusquedaPrimeroElMejor import buscaPM\n\n# Representaci\u00f3n del problema\n# ===========================\n\nclass Ficha(Enum):\n    B = 0\n    V = 1\n    H = 2\n\n    def __repr__(self) -> str:\n        return self.name\n\nB = Ficha.B\nV = Ficha.V\nH = Ficha.H\n\nTablero = list[Ficha]\n\n# tableroInicial(m, n) representa el tablero inicial del problema de las fichas\n# de orden (m,n). Por ejemplo,\n#    tableroInicial(2, 3)  ==  [B,B,H,V,V,V]\n#    tableroInicial(3, 2)  ==  [B,B,B,H,V,V]\ndef tableroInicial(m: int, n: int) -> Tablero:\n    return [B]*m + [H] + [V]*n\n\n# tableroFinal(m, n) representa el tablero final del problema de las fichas de\n# orden (m,n). Por ejemplo,\n#    tableroFinal(2, 3)  ==  [V,V,V,H,B,B]\n#    tableroFinal(3, 2)  ==  [V,V,H,B,B,B]\ndef tableroFinal(m: int, n: int) -> Tablero:\n    return [V]*n + [H] + [B]*m\n\n# posicionHueco(t) es la posici\u00f3n del hueco en el tablero t. Por\n# ejemplo,\n#    posicionHueco(tableroInicial(3, 2))  ==  3\ndef posicionHueco(t: Tablero) -> int:\n    return t.index(H)\n\n# intercambia(xs, i, j) es la lista obtenida intercambiando los\n# elementos de xs en las posiciones i y j. Por ejemplo,\n#    intercambia(1, 3, tableroInicial(3, 2))  ==  [B, H, B, B, V, V]\ndef intercambia(i: int, j: int, t: Tablero) -> Tablero:\n    t1 = t.copy()\n    t1[i], t1[j] = t1[j], t1[i]\n    return t1\n\n# tablerosSucesores(t) es la lista de los sucesores del tablero t. Por\n# ejemplo,\n#    >>> tablerosSucesores([V,B,H,V,V,B])\n#    [[V,H,B,V,V,B],[H,B,V,V,V,B],[V,B,V,H,V,B],[V,B,V,V,H,B],\n#     [V,B,B,V,V,H]]\n#    >>> tablerosSucesores([B,B,B,H,V,V,V])\n#    [[B,B,H,B,V,V,V],[B,H,B,B,V,V,V],[H,B,B,B,V,V,V],\n#     [B,B,B,V,H,V,V],[B,B,B,V,V,H,V],[B,B,B,V,V,V,H]]\ndef tablerosSucesores(t: Tablero) -> list[Tablero]:\n    j = posicionHueco(t)\n    n = len(t)\n    return [intercambia(i, j, t)\n            for i in [j-1,j-2,j-3,j+1,j+2,j+3]\n            if 0 <= i < n]\n\n# Heur\u00edstica\n# ==========\n\n# heuristicaT(t) es la heur\u00edstica del tablero t. Por ejemplo,\n#    heuristicaT([B,V,B,H,V,V,B]) == 5\ndef heuristicaT(t: Tablero) -> int:\n    if not t:\n        return 0\n    f, *fs = t\n    if f in {V, H}:\n        return heuristicaT(fs)\n    return heuristicaT(fs) + len([x for x in fs if x == V])\n\nclass Estado(list[Tablero]):\n    def __lt__(self, e: list[Tablero]) -> bool:\n        return heuristicaT(self[0]) < heuristicaT(e[0])\n\n# inicial(m, n) representa el estado inicial del problema de las fichas\n# de orden (m,n). Por ejemplo,\n#    inicial(2, 3)  ==  [[B,B,H,V,V,V]]\n#    inicial(3, 2)  ==  [[B,B,B,H,V,V]]\ndef inicial(m: int, n: int) -> Estado:\n    return Estado([tableroInicial(m, n)])\n\n# esFinal(m, n, e) se verifica si e es un estado final del problema de las\n# fichas de orden (m,n). Por ejemplo,\n#    >>> esFinal(2, 1, [[V,H,B,B],[V,B,B,H],[H,B,B,V],[B,B,H,V]])\n#    True\n#    >>> esFinal(2, 1, [[V,B,B,H],[H,B,B,V],[B,B,H,V]])\n#    False\ndef esFinal(m: int, n: int, e: Estado) -> bool:\n    return e[0] == tableroFinal(m, n)\n\n# (sucesores n) es la lista de los sucesores del estado n. Por ejemplo,\n#    >>> sucesores([[H,B,B,V],[B,B,H,V]])\n#    [[[B,H,B,V],[H,B,B,V],[B,B,H,V]],\n#     [[V,B,B,H],[H,B,B,V],[B,B,H,V]]]\n#    >>> sucesores([[B,H,B,V],[H,B,B,V],[B,B,H,V]])\n#    [[[B,V,B,H],[B,H,B,V],[H,B,B,V],[B,B,H,V]]]\ndef sucesores(e: Estado) -> list[Estado]:\n    t, *ts = e\n    return [Estado([t1] + e) for t1 in tablerosSucesores(t) if t1 not in ts]\n\n# Soluci\u00f3n por b\u00fasqueda\n# =====================\n\nBusqueda = Callable[[Callable[[Estado], list[Estado]],\n                     Callable[[Estado], bool],\n                     Estado],\n                    Optional[Estado]]\n\ndef fichas(b: Busqueda, m: int, n: int) -> Optional[list[Tablero]]:\n    r = partial(b, sucesores, lambda e: esFinal(m, n, e), inicial(m, n))()\n    if r is None:\n        return None\n    return [list(reversed(es)) for es in r]\n\n# Verificaci\u00f3n\n# ============\n\ndef test_fichas() -> None:\n    assert fichas(buscaProfundidad1, 1, 2) == \\\n        [[B, H, V, V], [B, V, V, H], [H, V, V, B], [V, V, H, B]]\n    assert fichas(buscaAnchura1, 1, 2) == \\\n        [[B, H, V, V], [B, V, V, H], [H, V, V, B], [V, V, H, B]]\n    assert fichas(buscaPM, 1, 2) == \\\n        [[B, H, V, V], [B, V, H, V], [H, V, B, V], [V, V, B, H],\n         [V, V, H, B]]\n    assert fichas(buscaEscalada, 1, 2) == \\\n        [[B, H, V, V], [H, B, V, V], [V, B, H, V], [V, H, B, V],\n         [V, V, B, H], [V, V, H, B]]\n    print(\"Verificado\")\n\n# La verificaci\u00f3n es\n#    >>> test_fichas()\n#    Verificado\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Para el problema de las fichas de orden (m,n) se considera un tablero con m+n+1 cuadrados consecutivos. Inicialmente, en cada uno de los m primeros cuadrados hay una blanca, a continuaci\u00f3n un hueco y en cada uno de los n \u00faltimos cuadrados hay una ficha verde. El objetivo consiste en tener las fichas verdes al&#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":[456],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/8267"}],"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=8267"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/8267\/revisions"}],"predecessor-version":[{"id":8268,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/8267\/revisions\/8268"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=8267"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=8267"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=8267"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}