@ agnasg

agnasg


“Traté con Java pero lo encontré increiblemente aburrido”

16-12-2010 10:06 AM

El Desafio de Inteligencia Artificial de Google es un concurso de programación y teoría de juegos que teminó recientemente (a principios de diciembre). El desafio consiste en diseñar un bot que pueda jugar con éxito un juego llamado Planetwar. En un mapa generado aleatoriamente, los dos jugadores comienzan con un planeta y 100 naves, la meta es acumular o mantener la mayoría de las naves luego de 200 turnos (cada turno dura 1 segundo ). El ganador fue Gábor Melis con su bot bocsimacko escrito en lisp. Planetwar es basado en Galcon, un juego disponible en flash, iphone y otras plataformas. Al ser consultado sobre por qué Lisp, Gábor Melis contestó: “Traté con Java pero lo encontré increiblemente aburrido”. Interesante forma de decirlo, o, quizás, otra forma sería “Lisp es más divertido”.

Para ilustrar esto, voy a poner como ejemplo una rutina que estaba estudiando anoche. Se trata de una función que invierte una lista. Es decir, dada una lista del tipo (1 2 3 4) la rutina debe devolver (4 3 2 1).  Y esta rutina la necesito porque quiero programar una rutina que me permita multiplicar dos vectores.

A continuación la rutina para invertir una lista (que se puede ver aqui):

(defun REV (L)
(cond
((null L) NIL)
(T (CAT (REV (cdr L)) (list (car L))))
)
)

La función CAT se supone que debe concatenar dos listas, y el autor propone una implementación. Innecesaria porque Lisp dispone de una función que concatena dos listas, se llama append. Anyway, esa rutina se lee de la siguiente forma: si la lista L está vacia se debe retornar NIL, sino está vacía se debe retornar la concatenación de la lista L sin el primer elemento ejecutada recursivamente por REV más una lista formada solamente por el primer elemento de L. cdr devuelve la lista que pasamos como argumento pero sin el primer elemento y car devuelve el primer elemento de la lista.

La ejecución es algo como lo siguiente: REV (1 2 3 4) se traduce en REV (2 3 4)  concatenado con (1). Es decir, el resultado va a ser algo concatenado con la lista (1). Luego REV (2 3 4) se traduce en REV (3 4) concatenado con (2) que a su vez está concatenado con la lista que conseguimos en la última llamada es decir (1). Hasta este momento tenemos  (2 1). REV (3 4) se traduce en REV (4) concatenado con (3) concatenado con (2 1) y la última llamada nos devuelve (4) lo que nos genera la solución final (4 3 2 1). ¿Divertido verdad?