King’s Quest II: Romancing the stones – El problema de los leones

GlimpG estuvo jugando King’s Quest II: Romancing the Stones esta semana, es un buen juego! y lo recomiendo a todo el que le gusten los point’n click. A diferencia de otros juegos del mismo género, en los que la solución a los acertijos es muy rebuscada, King’s Quest me pareció un juego bastante coherente.

Luego de muchas aventuras, te topas con uno de esos “clásicos” problemas de Knights and Knaves , sin embargo, este no es taan clásico, tiene algunas diferencias que llamaron mi atención…

Llegas a una torre, cuya puerta necesitas abrir, dos leones de piedra están a ambos lados de la torre. Y esta es toda la información que se te da, a partir de ese momento:

primer-dialogo

La verdad sabrás, de uno como yo
Ya que el otro, solo podría estar mintiendo.
Estas palabras te proveerán la forma de entrar.
Por el contrario, las de mi compañero, te van a matar.

(en inglés, está en proza, pero me da flojera ponerlo en proza en español XD)

Al hablar con cada uno de los leones, por separado, esta es la información que te dan:

leones

Luego de decirte esto, te dan “la combinación” para abrir la puerta.

¿Cuál de las combinaciones deberías poner en la puerta? ¿la que te da el león de la derecha? ¿o la que te da el león de la izquierda?

Usaremos una técnica para probar la veracidad de argumentos: Demostración por reducción al ridículo, también conocida como demostración por contradicción. Mediante esta técnica, llegaremos a la respuesta correcta… a los lectores que son nuevos en el campo de las demostraciones (o alérgicos a la jerga matemática), por favor, no se escapen aún @.@ intentaré escribir, de tal forma, que puedan entenderme :)

La estrategia es asumir un hecho (que no conocemos), como verdadero, y comenzar a ver qué conclusiones podemos sacar, encajando este nuevo hecho en los hechos que ya conocemos.

¿Cuáles son los hechos que conocemos?

(1) sabemos que el león de la izquierda, dijo que su compañero dirá que no sabe cómo abrir la puerta.

(2) sabemos que el león de la derecha, dijo que su compañero dirá que sí sabe cómo abrir la puerta.

(3) Y, obviamente, sabemos que una de las combinaciones, de alguno de los leones, nos matará, mientras que la otra, abrirá la puerta.

(4) de lo que dicen los leones, podemos leer entre líneas, y determinar que uno de los leones está mintiendo, mientras que el otro está diciendo la verdad

¿Cuáles son los hechos que no conocemos?

Muchos! XD pero podemos empezar con el que es más importante:

No sabemos cuál león está mintiendo y cuál está diciendo la verdad.

Ejecutando la estrategia

Supongamos que sabemos cuál león está mintiendo, y cuál está diciendo la verdad. Así que elegiremos, arbitrariamente, cuál león dice la verdad, y cuál está mintiendo. Luego, jugaremos con los hechos hasta encontrar una contradicción (o hasta estar seguros de que nuestra suposición podría resultar ser cierta.

Caso 1: El león de la izquierda dice la verdad

**Suposición** Supongamos que el león de la izquierda está diciendo la verdad, mientras que el león de la derecha está mintiendo.

Si el león de la izquierda está diciendo la verdad, entonces, su compañero, responderá que sí sabe cómo entrar.

Si el león de la izquierda dice la verdad, entonces su compañero responderá “no”.

Si el león de la izquierda es el que dice la verdad, el otro león no puede más que mentir, así que, al decir “no”, también estaría mintiendo, lo que implica que él sí sabría cómo abrir la puerta, pero como miente, la combinación que te diga, será falsa, y te matará.

**Conclusión 1**: el león que miente (el de la izquierda) sabe cómo abrir la puerta.

Hasta aquí, no hemos encontrado ninguna contradicción. Este hecho aún podría ser verdad.

Además, si el león de la derecha solo puede mentir, su compañero (el león de la izquierda), te dirá que no sabe cómo abrir la puerta. Pero como el león de la izquierda dice la verdad, entonces, sería verdad que no sabe cómo abrir la puerta.

Conclusión: el león que dice la verdad (el de la derecha), no sabe cómo abrir la puerta

Y aquí viene la contradicción: ambos leones te dicen una combinación para abrir la puerta, si el león que dice la verdad no supiera cómo abrir la puerta, simplemente te diría “no sé la combinación para abrir la puerta”, porque siempre dice la verdad.

Conclusión final: Por lo tanto, es imposible que el león de la izquierda esté diciendo la verdad.

Esta conclusión ya es suficiente para determinar cuál león miente y cuál león dice la verdad:

Si es imposible que el león de la izquierda diga la verdad, y a consecuencia de esto, el león de la derecha mienta, entonces el león de la izquierda no puede más que estar mintiendo, y la forma de abrir la puerta del león de la derecha tiene que ser, la forma correcta (es lo que los leones dicen, recuerdas?).

Sin embargo, aún me queda curiosidad por saber si es consistente que el león de la derecha esté diciendo la verdad. Después de todo, estás en una isla extraña, con agua púrpura, obedeciendo la voz de leones de piedra… no te daría miedo obedecer ciegamente? (a mí sí XD), y por eso, a continuación, está la prueba de que el león de la derecha está diciendo la verdad:

Caso 2: El león de la derecha dice la verdad

** Suposición ** Supongamos que el león de la derecha dice la verdad.

Si el león de la derecha dice la verdad, entonces, si le preguntas a su compañero si sabe cómo abrir la puerta, responderá “sí”.

Como el león de la izquierda no puede más que mentir, si él dice que sí sabe cómo abrir la puerta, estaría mintiendo: en realidad, no sabe cómo abrir la puerta.

Conclusión: el león que miente (el de la izquierda) no sabe cómo abrir la puerta.

Lo cuál tiene sentido, porque si no sabe cómo abrir la puerta, y además es un mentiroso, cuando te diga la combinación para abrir la puerta, estará mintiendo, y te verá morir si le obedeces.

Si el león de la izquierda está mintiendo, entonces, cuando le preguntes al león de la derecha si sabe cómo abrir la puerta, te responderá “sí”.

Como el león de la derecha dice la verdad; al decir que sí sabe cómo abrir la puerta, estará diciendo la verdad también.

Conclusión: el león que dice la verdad (el de la derecha) sí sabe cómo abrir la puerta.

Conclusión final: Si el león que dice la verdad sabe cómo abrir la puerta, si le preguntas cómo abrirla, y te dice una combinación, esta combinación abrirá la puerta.

Parece que el segundo caso es consistente, mientras que el primer caso, te lleva a una contradicción.

Y es por eso, que ésta técnica se llama “Demostración por contradicción” :)

Haciendo snippets con yasnippet

Hace muuucho tiempo prometí que escribiría una guía sobre cómo usar emacs para programar cosas web, y luego me olvidé ‘¬’

bueno, hoy lo volví a recordar XD

Recordarás que ya había escrito algo sobre cómo instalar yasnippet , esta vez quisiera compartir algunos snippets rápidos que creé, y que ahora los uso todo el tiempo mientras programo “cosas” web.

Pero más que compartir snippets ya hechos, quiero mostrarte cómo crear tus propios snippets, y algunas ideas para usar los snippets para aprender a usar librerías nuevas. Pero vamos en orden XD

No es necesario, pero talvez quieras instalarte primero web-mode (que te proveerá highlighting para php).

Lo que sí necesitarás, es yasnippet.

0. ¡¿qué es un snippet?!

Un snippet es un trozo de código que puedes “invocar” con una palabra clave. (Como el

 syso -> System.out.println(); de eclipse 

)

1. Haciendo tu propio snippet

Para crear un snippet para un mode de emacs, necesitas crear un archivo con la información del snippet en el directorio

 ~/.emacs.d/snippet/xxx-mode 

. En donde ‘xxx’ es el nombre del mode.

Por ejemplo, si quiero crear un snippet para javascript, tengo que crear un archivo llamado

 ~/.emacs.d/snippet/js-mode/mi-snippet 

.

El contenido de ese archivo debe ser algo así:

 
  # name: nombre
  # key: clave
  # --
  hola snippet

“clave” es la palabra clave que usarás para invocar al snippet. Puedes tener varios snippets con la misma clave, y allí es donde entra la importancia del “nombre”. Cuando tienes varios snippets que invocar con la misma palabra clave, te saldrá un menú desde el que puedes elegir cuál es el snippet que quieres elegir. Si le haz puesto nombre a tu snippet, entonces, el texto que esté en “nombre”, será el texto que se mostrará en ese menú.

Ahora, para probar tu nuevo snippet, abre un archivo javascript: “archivo.js”, luego: “M-x yas-reload-all” (eso hará que el snippet que acabas de crear se registre, sin tener que reiniciar tu emacs), ahora, en ese archivo, escribe “nombre”, y presiona “TAB” (o la tecla que uses para expandir un snippet). Si lo haz hecho bien, la palabra “nombre” debería desaparecer, y en vez de ella, apareció “hola snippet” (que es el código predefinido que escribimos en el snippet)… … genial, no? :D

Se pueden hacer cosas más complicadas con un snippet. Puedes poner campos de texto dentro del código predefinido… es complicado de explicar XD lo entenderás mejor si lo pruebas…

1.1 Un ejemplo dice más que mil palabras.

Antes de leerte todo este blog, talvez quieras probar este snippet, que probablemente despejará todas tus dudas, y así puedas saltarte a la 2da parte: usando snippets para aprender cosas nuevas.

 
  # name: un snippet esclarecedor
  # key: tutorial
  # --
  for (int ${1:i}=${2:0}; $1 < ${3:n}; ${4:$1++}) {
    $0
  }

Entendido? no? bueno… entonces lee el resto del blog XD

1.2 Un snippet más complicado

Ahora, haremos un snippet para hacer un div. Generalmente, cuando hacemos aplicaciones web, queremos hacer divs, y estos divs suelen tener clases diferentes. El div es el mismo, lo único que cambia, es su clase (y talvez, su id), algo así:

 
  <div class="esto siempre cambia" id="y esto también">  
    este es el contenido del div :P
  </div>

Vamos a hacer un snippet para “optimizar” el div xD

Crea un snippet llamado

 ~/.emacs.d/snippet/html-mode/tutorial-div 

el contenido es:

 
  # name: div class id
  # key: div
  # --
  <div class="$1" id="$2"> $0 </div>

Este snippet es igualito al que hicimos antes, la única diferencia son los “$”. Abre un archivo html y pruébalo por tu cuenta.

Notarás que el cursor ya no está al final del código predefinido, ahora está en “$1”, y el “$1” ha desaparecido. Prueba escribir algo, y a continuación, presionar “TAB”. Ahora el cursor se detuvo en el “$2”. Escribe algo de nuevo, y presiona tab. Ahora, el cursor se detuvo en $0, y el fondo de lo que escribes ya no está resaltado. “El snippet ha terminado”, y el cursor se quedó en $0.

1.3 Un snippet con texto por default

Suele pasar que, una porción de texto del código necesita ser cambiada, pero no muy seguido… por lo general, no cambia. Para esto, se le puede poner texto por defecto a cada snippet.

Por ejemplo, cuando comenzamos a hacer una página web, el idioma suele ser el español, pero podría ser otro.

Este snippet llamado

 ~/.emacs.d/snippet/html-mode/tutorial-html 

, escribe el esqueleto de un html:

 
  # name: esqueleto de html
  # key: html
  # --
  <!DOCTYPE html>
  
  <html lang="${1:es}">
    <head>
      <meta charset="${2:utf-8}" />
      <title>$3</title>
    </head>
    
    <body>
      $0
    </body>
  </html>

De nuevo, abre un archivo html, reinicia yasnippet con “M-x yas-reload-all”, y prueba el snippet con “html” “TAB”. Esta vez, el cursor se detendrá en lang=”…”, y, por defecto, estará escrito “es”, pero… en cuanto escribas algo, se borrará “es”, y se reemplazará por lo que escribas. Lo mismo pasará con charset. Luego, en title, pasará lo que ya expliqué en la sección anterior, y el snippet terminará, y el cursor se quedará dentro de body.

1.4 Reusando el texto

A veces, queremos reusar el texto que ya hemos escrito (como con los \begin{environment} \end{environment} de LaTeX, o con los tags de html).

Este es uno de los snippets que tengo en mi “arsenal” XD

 
  # name: generic tag
  # key: <
  # --
  <$1$2> $0 </$1>

De nuevo, abre un archivo html, reinicia yasnippet, y prueba el snippet que acabas de hacer escribiendo “<" "TAB". en $1, escribes el nombre del tag, observa cómo lo que escribes al abrir el tag, también se escribe cerrando el tag. Al presionar tab, puedes escribir las opciones del tag. Por último, el snippet se sale, y el cursor se queda en $0.

La segunda parte: usando snippets para aprender cosas nuevas, la escribiré después, me da flojera XD