Cruce de listas

En esta entrada comento las soluciones en Haskell y Maxima de un problema planteado por Adam Majewski en la lista de Maxima en forma de ejercicio para I1M y PD. Además, añadiré soluciones en otros lenguajes conforme las vaya recibiendo.

1. Solución en Haskell

En este ejercico se usarán las siguientes librerías


Ejercicio 1. Definir la función

tal que (cruce xs ys) es la lista de las listas obtenidas con uniendo las listas de xs sin un elemento con las de ys sin un elemento. Por ejemplo,



Solución:


Ejercicio 2. Comprobar con QuickCheck que el número de elementos de (cruce xs ys) es el producto de los números de elementos de xs y de ys.


Solución:
La propiedad es

La comprobación es

2. Solución en Maxima


Ejercicio 1. Definir la función cruce tal que cruce(xs,ys) es la lista de las listas obtenidas con uniendo las listas de xs sin un elemento con las de ys sin un elemento. Por ejemplo,


Solución:

3. Solución en Lisp

Una definición en Lisp-puro, aportada por Julio Rubio, es la siguiente

La evaluación de los ejemplos es

4. Solución en Prolog

Una definición del cruce en Prolog es

La evaluación de los ejemplos es

5. Simplicidad

Un parámetro para comparar la simplicidad de las definiciones es el número de palabras usadas en su definición, incluyendo las usadas en las definiciones auxiliares. Por lo que respecta a la función cruce, ls simplicidad de las distintas definiciones es

Haskell 25 palabras
Maxima 39 palabras
Prolog 44 palabras
Lisp 104 palabras

6. Eficiencia

Siguiendo la sugerencia de Gonzalo Aranda, he comparado la eficiencia de las implementaciones de las distintas definiciones en sus correspondientes lenguajes. Para ello, he medido el tiempo empleado en calcular el cruce de la lista formada por los N primeros números con ella misma para N igual a 100, 200, 300, 400 y 500.

Los experimentos han sido los siguientes:

Experimentos en Haskell con GHC 6.12.1

Experimentos con Maxima 5.20.1

Experimentos en Lisp con GNU CLISP 2.44.1

En Clisp puede compilarse obtenindo los siguientes resultados

Experimentos en Prolog con SWI Prolog, Version 5.8.0:

En la siguiente tabla se resumen de tiempos (en segundos) de los experimentos es
<br />   \begin{array}{|l|r|r|r|r|r|} \hline<br />    Lenguaje       & N=100 & N=200 & N=300 & N=400 & N=500 \\ \hline<br />    Haskell          &   0.03 &    0.06 &  0.12 &  0.20 &  0.29 \\ \hline<br />    Lisp           &  0.67 &  5.73 & 18.46 & 40.66 &     \\ \hline<br />    Lisp\ compilado &  0.44 &  4.40 & 11.47 & 32.55 &     \\ \hline<br />    Maxima    	   &  1.04 &  8.82 &     &     &     \\ \hline<br />    Prolog   	   &  1,58 &     &     &     &    \\ \hline<br />   \end{array}<br />

Estos tiempos dependen evidentemente del ordenador y de la versión del lenguaje que se utilice.

7. Comentarios

Este ejercicio se añadirá a los libros Ejercicios de programación en Haskell e Introducción al Cálculo simbólico con Maxima.

Es el primer ejercicio del libro de Maxima que usa la función create_list. El uso de dicha función hace que las definiciones en Haskell y Maxima sean semejantes.