jueves, 21 de septiembre de 2017

Resolución de acertijo con Python 3

El otro día, un amigo estaba leyendo el periódico y se topó con un acertijo que consideró interesante. Iba todo bien hasta que han comenzado a suceder cosas raras, vale, vale, es broma... me centro. Me lo enseñó y rápidamente nos pusimos manos a la obra para resolverlo. El acertijo es éste: (Está un poco pintado, pero se puede leer)

Como puedes leer, consiste en hallar una palabra de 5 letras que cumpla las siguientes normas:

  • Solo puede contener las letras que aparecen en el acertijo (ninguna otra).
  • De cada fila, deben aparecer tantas letras como se indica en el primer número de dicha fila.
    Por ejemplo: la palabra solución del acertijo, debe contener dos letras (ni más ni menos) de la segunda fila, donde pone "MORSA", porque así lo indica el primer número de dicha fila en la palabra solución.
    Otro ejemplo: la palabra solución no debe contener letras de la primera fila, porque así lo indica el primer número (que es un 0).
  • De cada fila, deben aparecer tantas letras en el mismo sitio como indica el segundo número de la fila. (Con letras "en el mismo sitio" o "en la misma posición" me refiero a letras en el mismo index, es decir, si la letra es la tercera de la fila, en la palabra solución también debe ser la tercera)
    Por ejemplo: la palabra solución debe contener una letra en el mismo sitio de la tercera fila, porque así lo indica el segundo número de ésta (un 1). O sea, de las letras A R D U O, una de ellas debe estar en el mismo sitio en la palabra solución. Pero ¡OJO! Solo una, más no.
    Otro ejemplo: la palabra solución debe contener una letra en el mismo sitio de la última fila, porque así lo indica el segundo número de ésta (un 1).

Nos pusimos con toda la ilusión del mundo a resolverlo, pero al cabo de un buen rato seguíamos sin conseguirlo (en parte por su dificultad y en parte porque no somos de la NASA). Viendo el panorama, se me ocurrió una idea para resolver el acertijo de una vez por todas: hacer un programa que lo resolviese. El programa está hecho, escribo este post, con el objetivo de mostrároslo y comentároslo.



NOTA: si te has fijado, en la imagen anterior hay algunas letras tachadas, ¿se te ocurre por qué puede ser? La primera fila, me dice que de sus letras, CERO están en la palabra solución (el primer número), por tanto, descarto estas letras con sus futuras apariciones en otras filas porque sé que esas letras NO VAN A PERTENECER A LA PALABRA SOLUCIÓN.

El programa
Antes de nada, puedes encontrarlo aquí.
O puedes descargarlo utilizando el comando git:
git clone https://github.com/jemonra/acertijoSUR.git

Lo primero, el programa está hecho en Python, porque es un lenguaje que puedo ejecutar tanto en mi Mac, como en mi PC, como en mi Raspberry... Y además, porque es un lenguaje que conozco más o menos bien. ¡Ah! y por supuesto en Python 3, que es el más reciente.

La idea del programa es que resuelva el acertijo anterior, ¿pero cómo? Probando todas las combinaciones de letras posibles en una palabra de 5 caracteres y comprobando cada una de las palabras resultantes con las normas de antes. Es decir, el programa va comprobando las normas que te he explicado antes (pero en Python, claro está) en bucle desde la palabra AAAAA hasta la palabra ZZZZZ. Y YA ESTÁ, ASÍ DE FÁCIL.

Pensarás que si el programa va probando una por una todas las palabras posibles, estaremos esperando a que termine hasta el año que viene, pero no es así. Hay 14.348.907 palabras comprobables, que para el ordenador son pan comido. En las pruebas que he hecho, el programa ha siempre ha durado unos 2 minutos y medio, tiempo que puede aumentar o disminuir dependiendo de las características de tu ordenador.

En resumen, el programa va probando una por una todas las combinaciones de letras posibles en una palabra de 5 letras y comprobando si siguen las normas del acertijo. Perfecto, el programa nos mostrará al final todas las palabras solución, pero claro, dentro de esas palabras solución habrá palabras que no tengan sentido alguno (como por ejemplo, una palabra solución de este acertijo que es: "COMUI") y palabras que sí lo tengan. Ver todas las palabras solución y decidir cual de ellas tiene sentido y existe, y cual no, es un trabajo que nos incumbe a nosotros ¿no?

Pues NO, yo no solo hice el programa con la idea de que mostrara todas las palabras solución, sino que también las buscara en un diccionario y me enseñara cuáles existen. "COMUI" por ejemplo es palabra solución, pero al buscarla en el diccionario, el programa ve que no existe y no la considera como "solución comprobada en el diccionario".

Vale, pero ¿que diccionario puedo usar en Python? Pues hice lo que se hace en esos casos en los que no tienes ni idea sobre algo, buscar en Google. Tuve la suerte de toparme con una librería python llamada Pyrae que permite hacer consultas de palabras en la RAE mediante internet. Era perfecta para lo que quería hacer. Y claro, pensé: ¿Qué diccionario va a estar más actualizado que la RAE? Me decanté por esta librería. Si te interesa, es de Ángel Carmona y puedes encontrarla aquí.

Entonces, cada vez que una palabra cumple las normas del acertijo, el programa la busca en la RAE y comprueba si existe en el diccionario o no (no es nada difícil, si la función de buscar palabras devuelve [], entonces la palabra no existe, si en cambio devuelve la definición... bingo!!). Pero a todo esto me surgió un problema y es que en el español también existen las TILDES. Si el programa por ejemplo me encontraba como palabra solución la palabra "arbol", la RAE me iba a decir que esa palabra no existía, porque la palabra que existe es "árbol" no "arbol" (por la tilde). Después de darle un poco al coco se me ocurrió el sistema de acentuación de vocales, que consiste en acentuar una por una las vocales de la palabra e ir comprobando esas nuevas palabras en la RAE; si no se encuentran ninguna de las palabras acentuadas, la palabra pasa a ser una "solución" pero sin la comprobación en la RAE.

Es decir:
  • El bucle pasa por la palabra ARBOL.
  • La palabra ARBOL respeta las normas del acertijo (es un caso hipotético, la palabra ARBOL no es solución de nuestro acertijo).
  • La palabra "arbol" es buscada en la RAE, como no existe se pasa a acentuar sus vocales.
  • La palabra "árbol" es buscada en la RAE, ¡existe! por lo que esta palabra pasa a ser una "solución encontrada en la RAE".
Veamos otro ejemplo:
  • El bucle pasa por la palabra ADIOS.
  • La palabra ADIOS respeta las normas del acertijo (es un caso hipotético, la palabra ADIOS no es solución de nuestro acertijo).
  • La palabra "adios" es buscada en la RAE, como no existe se pasa a acentuar sus vocales.
  • La palabra "ádios" es buscada en la RAE, como no existe se pasa a acentuar la siguiente vocal.
  • La palabra "adíos" es buscada en la RAE, como no existe se pasa a acentuar la siguiente vocal.
  • La palabra "adiós" es buscada en la RAE, ¡existe! por lo que esta palabra pasa a ser una "solución encontrada en la RAE".
Y otro ejemplo:
  • El bucle pasa por la palabra IMERT
  • La palabra IMERT respeta las normas del acertijo (es un caso hipotético, la palabra IMERT no es solución de nuestro acertijo).
  • La palabra "imert" es buscada en la RAE, como no existe se pasa a acentuar sus vocales.
  • La palabra "ímert" es buscada en la RAE, como no existe se pasa a acentuar la siguiente vocal.
  • La palabra "imért" es buscada en la RAE, como no existe y la "e" es la última vocal, la palabra IMERT pasa a ser una "solución" pero no una "solución encontrada en la RAE".
Espero que con estos tres ejemplos lo hayas comprendido todo.

Al final del programa, se imprime una lista con las soluciones y otra con las soluciones encontradas en la RAE. La segunda tiene más importancia y más probabilidad de ser la solución del acertijo, claro está.

Además, para que el programa fuera más "universal", contiene una variable llamada deducción donde está la tabla con las letras y los números del acertijo, para que así, si quieres resolver otro acertijo de este tipo, solo tengas que cambiar estos valores, y todo siga funcionando igual.

Requisitos
Como he dicho, el programa usa la librería Pyrae para ejecutarse, y para poder usar esta librería debemos instalar otras librerías (nombradas también en el archivo requirements.txt de la carpeta de la librería):
  • bs4 o Beautiful Soup 4.4.0. ¡Oh no! ¿Cómo se instala? Lo tienes en la parte Installing Beautiful Soup de esta página (siempre para Python 3).
  • lxml. En la parte Installation  de este tutorial encontrarás la instalación.
  • requests. Para la instalación, si no tienes instalado pipenv, mira el apartado Get the source code de este tutorial . En caso afirmativo, mira el apartado pipenv install requests y comandos que te ahorras.
Si eres principiante en este tema de Python e instalar librerías usando comandos, puede que te resulten liosos e incluso difíciles, pero NO TE PREOCUPES, a mi me paso igual. Es solo cuestión de acostumbrarse y de leer mucho sobre el tema.

¡ATENCIÓN! Si tienes dos versiones de Python instaladas en tu ordenador, utiliza pip3 en lugar de pip  para evitar complicaciones de versiones.

Si tienes algún problema con la instalación de cualquiera de las librerías, pon tu comentario y estaré encantado de ayudarte.

Okay, pero ¿cómo ejecuto el programa?
Una vez lo tengamos todo instalado, tenemos que iniciar el programa. Esto se hace así:
  • Abrimos el terminal o la línea de comandos (cmd en Windows).
  • Navegamos hasta la carpeta del programa con el comando cd. Por ejemplo: cd C:/Users/jemon/Desktop/acertijo_SUR_10_9_2017/ en Windows.
  • Una vez ahí, ejecutamos el programa con python acertijo.py o si tienes dos versiones de Python instaladas (la 2 y la 3 por ejemplo) python3 acertijo.py.
  • Si ves: Inicio del programa, descifrando el acertijo... es que todo ha ido bien, y solo te queda esperar a que el programa encuentre la solución o palabra común.

La solución
El programa para descifrar el acertijo lo tienes arriba, pero no te voy a dejar con la intriga... Y, finalmente, la palabra solución del acertijo es...


¡¡¡Sííííí!!!, como verás abajo donde pone: Palabras encontradas en la RAE, la solución del acertijo es la palabra común, una bonita palabra que me ha dado más de un quebradero de cabeza.

Cualquier duda, corrección, o pregunta... POR FAVOR no dudes en dejar un comentario, que estaré encantado de responderte y ayudarte lo máximo posible. 😁

Finalmente, solo me queda decir que gracias por leer este tutorial y que espero haberte ayudado lo máximo posible,  no olvides compartir si te ha gustado y darle al botón G+. 😉

No hay comentarios:

Publicar un comentario