Laborator 7

Laborator 7

Problema 1

Cod:

(defun sumaPozPar(lista) (if(null lista) 0 (+ (car lista) (sumaPozPar(cddr lista))

)

)

)

Apelare: (sumaPozPar '(1 2 3 4 5))

Rezultat obtinut: 9

Explicatii:

Parcurg lista recursiv si adun primul element al listei curente, actualizarea listei facut-o cu cate doua pozitii de fiecare data (cddr).

Problema 2

Cod:

(defun exista(element lista) (if(member element lista :test 'equal) t nil))

(defun reuniuneTrisata(lista1 lista2) (append lista1 (diferenta lista2 lista1)))

(defun reuniune(lista1 lista2) ( remove-if-not '(lambda(x) (exista x (reuniuneTrisata lista1 lista2)) ) (reuniuneTrisata lista1 lista2)) )

(defun intersectie(lista1 lista2) ( remove-if-not '(lambda(x) (exista x lista2) ) lista1) )

(defun diferenta(lista1 lista2) ( remove-if-not '(lambda(x) (not (exista x lista2) ) ) lista1) )

_____________________________________

(defun reuniune (lista1 lista2)

(if (null lista2)

lista1

(append (reuniune lista1 (cdr lista2))

(remove-if-not '(lambda(x) (not (exista x lista1)))(list (car lista2))

)

)

)

)

Apelare:

(reuniune '(1 2 3 (7 8 (9)) (7 8 9) ) '(4 3 (7 8 9)))

(intersectie '(1 2 3 4 (4 5 6) 8 9) '(3 4 (4 5 6) 9))

(diferenta '(1 2 3 4 (4 5 6) 8 9) '(3 4 (4 5 6) 9))

Rezultat obtinut:

(1 2 3 (7 8 (9)) (7 8 9) 4)

(3 4 (4 5 6) 9)

(1 2 8)

Explicatii:

Folosesc functia "exista" pentru a verifica daca un element, fie el si lista se regaseste in a doua lista.

Reuniune: Functia "reuniuneTrisata" genereaza reuniunea celor doua multmi ca si concatenare a primei liste cu diferenta dintre a doua si prima lista. Adica prima lista + tot ce se afla in a doua lista si nu se afla in prima.

Pentru ca eram nevoit sa folosesc functia "remove-if-not", tot ce am facut a fost sa verific daca fiecare element din reuniune se afla in reuniune. Din acest motiv am zis "trisat".

Intersesctie : Elimin elementul care nu satisface conditia de la functia "exista".

Diferenta: Elimin elementul care nu satisface conditia negata de la functia "exista".

_____________

“Metoda 2” este fortata, foarte contraintuitiva, si nu este deloc o solutie eleganta. Eu prefer prima metoda.

Problema 3

Cod:

(setq l '(0 5 10 ( (15) (5) (((5))) ) 2 3 4 5))

(defun numarAparitii(l n) (cond ( (atom l) (cond ( (= l n) 1)

(t 0)

)

)

(t (apply '+ (mapcar '(lambda(x) (numarAparitii x n)) l)

)

)

)

)

Apelare: (numarAparitii l 5)

Rezultat obtinut : 4

Explicatii:

Suma o calculez in mod recursiv.

Daca elementul curent este atom si este egal cu elementul cautat, returnez 1, care va fi adunat la suma. In caz ca nu este egal cu elementul cautat, returnez 0.

In cazul in care elementul curent este o lista, aplic "+" pe fiecare element al liste formate in mod recursiv cu ajutorul lui "mapcar", lista obtinuta folosindu-se "mapcar" pe fiecare element al listei initiale. Astfel este definita si recursivitatea.

Exemplificare:

Cand programul ajunge la elementul " ( (15) (5) (((5))) ) " , acesta va aplica aceea functie lambda pe fiecare element al acestei lista. Astfel primul element va fi "(15)" Acesta este o lista, se va aplica din nou functia lambda pe aceasta lista. Astfel acum elementul este "15", este atom, si se verifica daca este egal cu "5". Nu este si se returneaza 0. Astfel un element al sumei este 0.

Problema 4

Cod:

/* Rescriere functii cu asezarea parantezelor mai orientativa

(defun print1-lista(l) (princ pard)

(do( (lst l (cdr lst))

) ( (null (cdr lst)) (princ (car lst)) (princ par) )

(princ (car lst)) (terpri)

)

)

(defun print-lista(l) (princ pard)

(do( (lst l (cdr lst))

) ((null lst) (princ par))

(princ (car lst)) (princ space)

)

)

*/

(setq pard '|{| )

(setq par '|}|)

(setq space '| |)

(defun afisareLista(l) (cond ( (atom l)

(princ l)(terpri)(princ space)

)

( t

(princ pard)

(mapcar '(lambda(x) (afisareLista x)) l)

(princ par) (terpri)

)

)

(princ space)

)

Apelare: (afisareLista '(a b (c d) (e f g) h))

Rezultat obtinut:

{A

B

{C

D

}

{E

F

G

}

H

}

| |

Explicatii:

Daca elementul curent este atom, il afisez, urmat de un rand nou si un spatiu. In caz contrar, folosesc pe fiecare element al listei aceasta functie(cu ajutorul lui mapcar) si afisez catea paranteze deschide, inchise, rand nou, respectiv spatiu. "| |" de la final apare deoarece la finalul executiei programului se returneaza ultima valoare a argumentului lui "princ".