ejerciciosLisp

10
Ejercicios B´ asicos de Lisp Ingenier´ ıa en Inform´ atica 1. Enunciados 1. Escribir la funcion rotar que rota los elementos de una lista hacia la derecha o hacia la izquierda > (rotar-derecha ’(1 2 3 4)) > (4 1 2 3) > (rotar-izquierda ’(1 2 3 4)) > (2 3 4 1) 2. Escribir la funci´ on calcula-cuadrados que recibe una lista de n ´ umeros y devuelve otra lista con el cuadra- do de cada elemento > (calcula-cuadrados ’(1 2 3 4)) > (1 4 9 16) 3. Escribir la funci ´ on cuenta-pares que recibe una lista y devuelve cuantos n´ umeros pares tiene > (cuenta-pares ’(1 2 3 4)) >2 4. Escribir la funci ´ on resta-listas que devuelve una lista con los elmentos de la primera lista que no aparecen en la segunda > (resta-listas ’(1 2 3 4) ’(2 3)) > (1 4) 5. Escribir la funci´ on suma-listas que devuelve una lista con los elementos de la primera lista y los de la segunda que no aparecen en la primera > (suma-listas ’(1 2 3 4) ’(2 3 5)) >(12345) 6. Escribir la funci ´ on get-posicion que determina la posici ´ on de un ´ atomo en la lista > (get-posicion ’c ’(a b c d)) >3 7. Escribir el predicado es-primo-p que indica si un n ´ umero es primo o no > (es-primo-p 10) > nil > (es-primo-p 5) >t 1

Transcript of ejerciciosLisp

Page 1: ejerciciosLisp

Ejercicios Basicos de LispIngenierıa en Informatica

1. Enunciados

1. Escribir la funcion rotar que rota los elementos de una lista hacia la derecha o hacia la izquierda

> (rotar-derecha ’(1 2 3 4))> (4 1 2 3)> (rotar-izquierda ’(1 2 3 4))> (2 3 4 1)

2. Escribir la funcion calcula-cuadrados que recibe una lista de numeros y devuelve otra lista con el cuadra-do de cada elemento

> (calcula-cuadrados ’(1 2 3 4))> (1 4 9 16)

3. Escribir la funcion cuenta-pares que recibe una lista y devuelve cuantos numeros pares tiene

> (cuenta-pares ’(1 2 3 4))> 2

4. Escribir la funcion resta-listas que devuelve una lista con los elmentos de la primera lista que no aparecenen la segunda

> (resta-listas ’(1 2 3 4) ’(2 3))> (1 4)

5. Escribir la funcion suma-listas que devuelve una lista con los elementos de la primera lista y los de lasegunda que no aparecen en la primera

> (suma-listas ’(1 2 3 4) ’(2 3 5))> (1 2 3 4 5)

6. Escribir la funcion get-posicion que determina la posicion de un atomo en la lista

> (get-posicion ’c ’(a b c d))> 3

7. Escribir el predicado es-primo-p que indica si un numero es primo o no

> (es-primo-p 10)> nil> (es-primo-p 5)> t

1

Page 2: ejerciciosLisp

8. Escribir la funcion invertir que invierte el contenido de una lista

> (invertir ’(1 2 3 4))> (4 3 2 1)

9. Escribir la funcion get-numeros que extrae todos los numeros que aparecen en una lista

> (get-numeros ’((1 (2)) a (((5 c 7))) 4))> (1 2 5 7 4)

10. Escribir la funcion get-profundidad que obtiene el numero maximo de listas anidadas que aparecen enuna lista

> (get-profundidad ’((1 (2)) (((5 7))) 4))> 3

11. Escribir una funcion que reciba una lista de numeros y retorne una lista de numeros sumandole su posi-cion a cada numero de la lista.

> (suma-posicion ’(1 3 7 -2))> (2 5 10 2)

12. Escribir la funcion calcula-diferencia que recibe una lista de numeros y devuelve otra lista con la difer-encia entre un numero y su sucesor en la lista. (El ultimo elemento no cuenta)

> (calcula-diferencia ’(10 6 2 5 -4))> (4 4 -3 9)

13. Escribir la funcion separa-parimpar que recibe una lista de numeros y retorna una lista con una sublistade los pares y otra sublista con los impares.

> (separa-parimpar ’(1 2 3 5 6 8 9 11 12))> ((12 8 6 2) (11 9 5 3 1))

14. Escribir la funcion cambia-notacion que transforme una expresion con operaciones matematicas escritasen notacion funcional de LISP a su notacion infija correspondiente.

> (cambia-notacion ’(+ (* 7 4) (* 5 3) (- (/ 30 (* 2 3)) 1)))> ((7 * 4) + (5 * 3) + ((30 / (2 * 3)) - 1))

15. Escribir una funcion que a partir de los elementos de una lista cree un conjunto de todos los posiblespares ordenados

> (pares-ordenados ’(a b c ))> ((A . B) (A . C) (B . A) (B . C) (C . A) (C . B))

16. Dada la siguiente estructura

(defstruct punto(valx 0)(valy 0))

17. Escribir una funcion que reciba como parametros 2 puntos y calcule la distancia euclıdea entre ellos.

2

Page 3: ejerciciosLisp

> (distancia-puntos (make-punto :valx 8 :valy 6) (make-punto))> 10

18. Escribir una funcion que convierta una lista de numeros en un vector de numeros con los mismos ele-mentos.

>(array-to-vector ’(1 2 3 4 6 7))> #(1 2 3 4 6 7)

19. Escribir una funcion que determine si una lista de numeros esta ordenada o no.

>(is-ordenada ’(1 3 5 7 10))> T>(is-ordenada ’(1 3 15 5 7))> NIL>(is-ordenada ’(15 11 3))> T

20. Escribir la funcion que divida una lista en 2 partes iguales y retorne una lista con las 2 nuevas sublistas(Si la cantidad de elementos es impar la primera sublista debera tener un elemento mas).

> (dividir-lista ’(a b c d e))> ((a b c) (d e))> (dividir-lista ’(1 2 3 4 5 6))> ((1 2 3) (4 5 6))

21. Escribir una funcion que a partir de una lista copie en un fichero “inversa.txt” la lista y la version invertidade la misma.

> (guarda-lista-invertida ’(w x y z ))> nil

22. Escribir una funcion que incremente en uno cada uno de los valores de una lista de numeros

> (incrementar-lista ’(5 3 2 0))> (6 4 3 1)

23. Escribir una funcion que devuelva una lista con sus elementos duplicados.

> (duplicar-lista ’(a b c))> (a b c a b c)

24. Escribir una funcion que reciba un nAomero y una lista de nAomeros y retorne una lista de numeros conel resto (modulo) de dividir cada elemento de la lista con el primer parametro.

> (lista-modulo 5 ’(1 6 10 23 54))> (1 1 0 3 4)

25. Escribir una funcion que relacione por posicion una lista de nombres con una lista de apellidos.

> (relacion-nombre-apellido ’(Javier Maria Miguel) ’(Arias Gonzalez Torres)> ((Javier Arias) (Maria Gonzalez) (Miguel Torres))

3

Page 4: ejerciciosLisp

26. Escribir una funcion que cambie el signo de los elementos en posicion par

> (cambia-signo-2n ’(5 7 -2 -3 1 2))> (5 -7 -2 3 1 -2)

27. Escribir una funcion que tome una lista de numeros e imprima por pantalla en cada lınea el numero nrepetido n veces.

> (imprimir-n-numeros ’(3 4 2))3 3 34 4 4 42 2> nil

28. Escribir una funcion que cuente las veces que aparece un sımbolo dado como parametro en un Arbol delistas.

> (ocurrencia-simbolo ’a ’((a b) a (1 3 (d (a)) 7)))> 4

29. Dada la siguiente estructura

(defstruct nodo(valor nil)(hijos nil))

Escribir una funcion que asigne al campo hijos de una estructura una lista de estructuras nodo con su elvalor correspondiente de una lista dada.

> (crea-hijos (make-nodo :valor 0) ’(1 2 3))#S(NODO :VALOR 0:HIJOS( #S(NODO :VALOR 3 :HIJOS NIL)#S(NODO :VALOR 2 :HIJOS NIL)#S(NODO :VALOR 1 :HIJOS NIL)))

30. Escribir una funcion que retorne un arreglo de longitud n conteniendo en cada posicion la suma acumu-lada de los numeros positivos hasta cada posicion.

>(arreglo-sumatoria 5)> #(1 3 6 10 15)

31. Escribir una funcion que invierta una matriz cuadrada de longitud n representada con una lista por cadafila.

> (invertir-matriz ’((1 2)(0 1))> ((1 0)(2 1))> (invertir-matriz ’((1 2 3)(4 5 6)(7 8 9))> ((1 4 7)(2 5 8)(3 6 9))

4

Page 5: ejerciciosLisp

2. Soluciones

1. Escribir la funcion rotar que rota los elementos de una lista hacia la derecha o hacia la izquierda

(defun rotar-derecha (lista)(append (last lista) (reverse (rest (reverse lista)))))

(defun rotar-izquierda (lista)(append (rest lista) (list (car lista))))

2. Escribir la funcion calcula-cuadrados que recibe una lista de numeros y devuelve otra lista con el cuadra-do de cada elemento

(defun calcula-cuadrados (lista)(mapcar #’(lambda(x) (* x x)) lista))

3. Escribir la funcion cuenta-pares que recibe una lista y devuelve cuantos numeros pares tiene

(defun cuenta-pares (lista)(count 0 (mapcar #’(lambda(x) (mod x 2)) lista)))

4. Escribir la funcion resta-listas que devuelve una lista con los elmentos de la primera lista que no aparecenen la segunda

(defun resta-listas (lista1 lista2)(remove nil (mapcar #’(lambda (x) (when (equal nil (find x lista2))

x))lista1)))

5. Escribir la funcion suma-listas que devuelve una lista con los elementos de la primera lista y los de lasegunda que no aparecen en la primera

(defun suma-listas (lista1 lista2)(remove-duplicates (append lista1 lista2)))

6. Escribir la funcion get-posicion que determina la posicion de un atomo en la lista

(defun get-posicion (elemento lista)(get-posicion-recursivo elemento lista 0))

(defun get-posicion-recursivo (elemento lista index)(if (> index (length lista)) nil

(if (equal elemento (nth index lista)) index(get-posicion-recursivo elemento lista (+ 1 index)))))

7. Escribir el predicado es-primo-p que indica si un numero es primo o no

(defun es-primo-p (numero)(es-primo-p-recursivo numero 2))

(defun es-primo-p-recursivo (numero divisor)(if (>= divisor numero) t

(if (= 0 (mod numero divisor)) nil(es-primo-p-recursivo numero (+ 1 divisor)))))

5

Page 6: ejerciciosLisp

8. Escribir la funcion invertir que invierte el contenido de una lista

(defun invertir (lista)(reverse lista))

9. Escribir la funcion get-numeros que extrae todos los numeros que aparecen en una lista

(defun get-numeros (lista)(remove nil (mapcar #’(lambda(x) (get-numeros-recursivo x)) lista)))

(defun get-numeros-recursivo (item)(if (numberp item) item

(mapcar #’(lambda(x) (get-numeros-recursivo x))item)))

10. Escribir la funcion get-profundidad que obtiene el numero maximo de listas anidadas que aparecen enuna lista

(defun get-profundidad (lista)(apply ’max (mapcar #’(lambda (x) (get-profundidad-recursivo x 0)) lista)))

(defun get-profundidad-recursivo (lista profundidad)(if (atom lista) profundidad

(apply ’max (mapcar #’(lambda(x) (get-profundidad-recursivo x (+ 1 profundidad)))lista))))

11. Escribir una funcion que reciba una lista de numeros y retorne una lista de numeros sumandole su posi-cion a cada numero de la lista.

(defun suma-posicion (list)(let ((aux))

(dotimes (i (length list))(push (+ (nth i list) i) aux))

(reverse aux)))

12. Escribir la funcion calcula-diferencia que recibe una lista de numeros y devuelve otra lista con la difer-encia entre un numero y su sucesor en la lista. (El ultimo elemento no cuenta)

(defun calcula-diferencia (list)(let ((aux))

(dotimes (i (length list))(when (< (+ i 1) (length list))

(push (- (nth i list) (nth (+ i 1) list)) aux)))(reverse aux)))

13. Escribir la funcion separa-parimpar que recibe una lista de numeros y retorna una lista con una sublistade los pares y otra sublista con los impares.

(defun separa-parimpar (list)(let ((par)

(impar))(dolist (item list)(if (oddp item)

(push item impar)(push item par)))

(list (reverse par) (reverse impar))))

6

Page 7: ejerciciosLisp

14. Escribir la funcion cambia-notacion que transforme una expresion con operaciones matematicas escritasen notacion funcional de LISP a su notacion infija correspondiente.

(defun cambia-notacion (list)(when (and (numberp (second list))

(numberp (third list)))(list (second list)

(car list)(third list))

(when (and (listp (second list))(listp (third list)))

(list (ejercicio4 (second list))(car list)(ejercicio4 (third list)))))

15. Escribir una funcion que a partir de los elementos de una lista cree un conjunto de todos los posiblespares ordenados

(defun pares-ordenados (list)(remove nil (mapcar #’(lambda (z) (when (not (equal (car z) (cdr z)))

z))(apply ’append(mapcar #’(lambda (x)

(mapcar #’(lambda (y) (cons x y))list))

list)))))

16. Dada la siguiente estructura

(defstruct punto(valx 0)(valy 0))

17. Escribir una funcion que reciba como parametros 2 puntos y calcule la distancia euclıdea entre ellos.

(defun distancia-puntos (punto1 punto2)(sqrt (+ (* (- (punto-valx punto1) (punto-valx punto2))

(- (punto-valx punto1) (punto-valx punto2)))(* (- (punto-valy punto1) (punto-valy punto2))

(- (punto-valy punto1) (punto-valy punto2))))))

18. Escribir una funcion que convierta una lista de numeros en un vector de numeros con los mismos ele-mentos.

(defun array-to-vector (list)(apply #’vector list))

19. Escribir una funcion que determine si una lista de numeros esta ordenada o no.

(defun is-ordenada (list)(equal (print list) (print (sort list ’<))))

7

Page 8: ejerciciosLisp

20. Escribir la funcion que divida una lista en 2 partes iguales y retorne una lista con las 2 nuevas sublistas(Si la cantidad de elementos es impar la primera sublista debera tener un elemento mas).

(defun dividir-lista(list)(let ((aux1 nil)

(aux2 nil))(dotimes (i (length list))

(when (<= (+ i 1) (/ (length list) 2))(push (nth i list) aux1))

(when (> (+ i 1) (/ (length list) 2))(push (nth i list) aux2)))

(list (reverse aux1) (reverse aux2))))

21. Escribir una funcion que a partir de una lista copie en un fichero “inversa.txt” la lista y la version invertidade la misma.

(defun guarda-lista-invertida (list file-name)(let ((output-file (open file-name :direction :output :if-does-not-exist :create)))

(format output-file "˜a˜&" list)(format output-file "˜a˜&" (reverse list))(close output-file)))

22. Escribir una funcion que incremente en uno cada uno de los valores de una lista de numeros

(defun incrementar-lista (lista)(when (listp lista)

(mapcar #’ (lambda (x) (+ 1 x)) lista)))

23. Escribir una funcion que devuelva una lista con sus elementos duplicados.

(defun duplicar-lista (lista)(when (listp lista) (append lista lista)))

24. Escribir una funcion que reciba un numero y una lista de numeros y retorne una lista de numeros con elresto (modulo) de dividir cada elemento de la lista con el primer parametro.

(defun lista-modulo (num lista)(when (listp lista)

(mapcar #’(lambda (x) (mod x num)) lista)))

25. Escribir una funcion que relacione por posicion una lista de nombres con una lista de apellidos.

(defun relacion-nombre-apellido (lista1 lista2)(when (and (listp lista1) (listp lista2))

(mapcar #’ (lambda (x y) (list x y)) lista1 lista2)))

26. Escribir una funcion que cambie el signo de los elementos en posicion par

(defun cambiar-signo-2n (lista)(when (listp lista)

(mapcar #’ (lambda (x) (if (oddp (position x lista)) (- 0 x) x)) lista)))

8

Page 9: ejerciciosLisp

27. Escribir una funcion que tome una lista de numeros e imprima por pantalla en cada lınea el numero nrepetido n veces.

(defun imprimir-n-numeros (lista)(when (listp lista)

(mapcar #’(lambda(x) (dotimes (a x)(format t "˜d " x))

(format t "˜%"))lista)nil))

28. Escribir una funcion que cuente las veces que aparece un sımbolo dado como parametro en un arbol delistas.

(defun ocurrencia-simbolo (simbolo lista)(cond((null lista) 0)((not (listp (car lista))) (if (equal simbolo (car lista))(+ 1 (ocurrencia-simbolo simbolo (cdr lista)))

(ocurrencia-simbolo simbolo (cdr lista))))(t (+ (ocurrencia-simbolo simbolo (car lista)) (ocurrencia-simbolo simbolo (cdr lista))))))

29. Dada la siguiente estructura

(defstruct nodo(valor nil)(hijos nil))

Escribir una funcion que asigne al campo hijos de una estructura una lista de estructuras nodo con su elvalor correspondiente de una lista dada.

(defun crea-hijos (nodo lista)(when (listp lista)

(make-nodo :valor 0 :hijos (mapcar #’(lambda (x) (make-nodo :valor x)) lista))))

30. Escribir una funcion que retorne un arreglo de longitud n conteniendo en cada posicion la suma acumu-lada de los numeros positivos hasta cada posicion.

(defun suma-acumulada (num)(when (numberp num)

(cond((zerop num) 0)(t (+ num (suma-acumulada (- num 1)))))))

(defun arreglo-sumatoria (num)(when (numberp num)

(let ((vector-resultado (make-array num :initial-element 0)))(dotimes (a num)

(setf (aref vector-resultado a) (suma-acumulada (+ 1 a))))vector-resultado)))

31. Escribir una funcion que invierta una matriz cuadrada de longitud n representada con una lista por cadafila.

9

Page 10: ejerciciosLisp

(defun obtener-elemento (int lista)(let ((elemento-n))

(dotimes (b (length lista))(setf elemento-n (append elemento-n (list (nth int (nth b lista))))))

elemento-n))

(defun invertir-matriz (lista)(when (> (length lista) 1)

(let ((lista-resultado))(dotimes (a (length lista))

(setf lista-resultado (append lista-resultado (list (obtener-elemento a lista)))))lista-resultado)))

10