Laborator 9

Laborator 9

Problema 1

Cod:

(setq m (make-array '(3 3)))

(setf (aref m 0 0) 0)

(setf (aref m 0 1) 1)

(setf (aref m 0 2) 2)

(setf (aref m 1 0) 3)

(setf (aref m 1 1) 4)

(setf (aref m 1 2) 5)

(setf (aref m 2 0) 6)

(setf (aref m 2 1) 7)

(setf (aref m 2 2) 8)

(setf space | |)

(defun print-array (matrice) ( do( (i 0 (+ i 1))

) ((= i (array-dimension matrice 0)) (princ space))

( do( (j 0 (+ j 1))

) ((= j (array-dimension matrice 1))(terpri))

(princ (aref matrice i j))

(princ space)

)

)

)

Apel: (print-array m)

Rezultat obtinut:

0 1 2

3 4 5

6 7 8

| |

Explicatii:

In aceasta parcurgere, "i" reprezinta numarul liniilor, iar "j" reprezinta numarul coloanelor.

"| |" se afiseaza datorita faptului ca princ returneaza valoarea ultimului argument, astfel cand ajungem cu "i" la final, se afiseaza acest caracter.

Problema 2:

Cod:

(defun nrElements(lista) (if(equal lista nil) 0 (+ 1 (nrElements(cdr lista)) ) ))

(defun countAtoms (lista)(if (equal lista nil) 0 (if (atom (car lista)) (+ 1 (countAtoms (cdr lista)))

(+ (countatoms (car lista)) (countatoms (cdr lista)) )

)

)

)

(defun transformare (lista) (

do( (i 0 (+ i 1)) (matrice (make-array (list (nrElements lista) (countAtoms (car lista)))

)

)

) ((= i (array-dimension matrice 0))matrice)

( do( (j 0 (+ j 1)) (firstElement (car lista) (cdr firstElement) )

) ((= j (array-dimension matrice 1))(princ space))

(setf(aref matrice i j)(car firstElement))

)

(setq lista (cdr lista))

)

)

(setq lista1 '((1 2 3) (4 5 6) (7 8 9)))

(defun primulDePeUltimaPoz(lista) ( car (car (last lista)

)

)

)

(defun alDoileaDePeUltimaPoz(lista) (car (cdr (car (last a)

)

)

)

)

(defun transformare2(lista)( setq matrice (make-array (list (+ 1 (primulDePeUltimaPoz lista)) (+ 1(alDoileaDePeUltimaPoz lista)))

)

)

(do( (aux lista (cdr aux))

) ((null aux) matrice)

(setf (aref matrice (car (car aux)) (car (cdr (car aux) ) )

) (car (last (car aux)) )

)

)

)

(defun nrEvenElements(matrice) ( do( (i 0 (+ i 1)) (count 0)

) ((= i (array-dimension matrice 0)) count)

( do( (j 0 (+ j 1))

) ((= j (array-dimension matrice 1))(princ space))

(if (= (mod (aref matrice i j) 2 ) 0)

(setq count (+ count 1) )

)

)

)

)

(setq lista2 '((0 0 1) (0 1 2) (0 2 3) (1 0 4) (1 1 5) (1 2 6) (2 0 7) (2 1 8) (2 2 9)))

Apel:

(setq matrice1 (transformare lista1))

(print-array matrice1)

(nrEvenElements matrice1)

(setq matrice2 (transformare2 lista2))

(print-array matrice2)

(nrEvenElements matrice2)

Rezultat obtinut:

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

1 2 3

4 5 6

7 8 9

| |

4

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

1 2 3

4 5 6

7 8 9

| |

4

Explicatii:

Functia "nrElements" numara cate elemente are o lista primita ca parametru.

Functia "countAtoms" numara cate elemente de tip atom exista intr-o lista.

Aceste doua functii de mai sus au fost facute in laboratoarele precedente.

Pentru cazul in care avem o matrice definita sub forma de lista de subliste in felul urmator: ((e1 e2 e3) (e4 e5 e6) ), inseamna ca numarul de linii al matricii va fi egal cu numarul de elemente de tip lista pe care le are aceasta lista, in cazul nostru de fata 2 elemente. Numarul de coloane este determinat de numarul de elemente dintr-o sublista, in cazul de fata 3. Pentru acest exemplu vom aveam o matrice cu 2 linii si 3 coloane. Pentru a determina aceste numere,ma folosesc de cele doua functii de mai sus.

Creez o noua matrice cu dimensiunile potrivite( determinate de aceste functii).

Variabila "firstElement" reprezinta primul element de tip sublista din lista primita ca parametru de functie.

Parcurg matricea creeata si ii setez fiecarui element valoarea potrivita. Acest lucru se face cu ajutorul variabilei "firstElement". Acesta se parcurge o data cu parcurgerea lui "j" (cdr firstElement), adica parcurgerea pe coloana. Acesta trece la urmatorul element, prin faptul ca parametrul functiei se reinitializeaza (cdr lista).

Obs:

Poate urmatoarea linie va parea neobisnuita:

(matrice (make-array (list (nrElements lista) (countAtoms (car lista)))

si urmatoarea linie va parea cea corecta:

(matrice (make-array '( (nrElements lista) (countAtoms (car lista)))

Insa cea din urma nu este corecta.

De exemplu, daca am fi avut '((length lista) 5) acesta s-ar fi evaluat la ((LENGTH lista) 5) . Astfel primul element nu ar fi fost un numar, ci doua expresii simbolice.

In lisp '((expresieSimbolica) 5) se evalueaza la ((EXPRESIESIMBOLICA) 5) , pe cand (list (expresieSimbolica) 5) evalueaza functia de la "expresieSimbolica" mai intai iar astfel rezultatul va fi:

(rezultat-apel-functie-expresieSimbolica 5)

In cazul reprezentarii listei sub forma : ( (i0 j0 e0) ((i1 j1 e1) ... ((in jm ek) )

Matricea ce o avem de construit are "n" linii si "m" coloane. Pur si simplu parcurgem lista primita ca argument si setam valoarea corespunzatoare la poztia indicata de indici din fiecare sublista.

Pentru a determina cate elemente pare are o matrice, procedez astfel: parcurg matricea, iar de fiecare data cand intalnesc un numar par, incrementez “count-ul”. La final il returnez.

Problema 3:

Cod:

(defstruct nod cheie stanga dreapta)

(setf radacina(make-nod :cheie 0 :stanga nil :dreapta nil))

(defun adaugaNod(nodCurent cheieNoua) (

if(< cheieNoua (nod-cheie nodCurent))

(if(equal (nod-stanga nodCurent) nil)

(setf(nod-stanga nodCurent) (make-nod :cheie cheieNoua))

(adaugaNod (nod-stanga nodCurent) cheieNoua)

)

(if(equal (nod-dreapta nodCurent) nil)

(setf(nod-dreapta nodCurent) (make-nod :cheie cheieNoua))

(adaugaNod (nod-dreapta nodCurent) cheieNoua)

)

)

)

Apel:

(adaugaNod radacina 1)

(adaugaNod radacina 2)

(adaugaNod radacina -1)

radacina

Rezultat obtinut:

(NOD CHEIE 0 STANGA #S(NOD CHEIE -1 STANGA NIL DREAPTA NIL) DREAPTA #S(NOD CHEIE 1 STANGA NIL DREAPTA #S(NOD CHEIE 2 STANGA NIL DREAPTA NIL)))

Explicatii:

Obs: Pentru a adauga in arbore, vom apela intotdeauna functia "adaugaNod" cu primul parametru fiind "radacina" arborelui.

Daca cheia pe care vrem sa o adaugam este mai mica decat cheia nodului curent inseamna ca aceasta trebuie sa fie adaugata in stanga acelui nod. In caz ca nu este nod terminal, continui deplasarea in mod recursiv pana ajung la un nod terminal. Astfel, cand ajung la un nod terminal, creez un nou nod si il setez pe stanga sau pe drepta in functie de caz.