#lang racket (display '::::::::::::::::::::::::::::::::::FUNCȚIONALE)(newline) (define M '( (1 2 3) (a b c) (X Y Z))) (define (d-m m) (map (λ (row) (display row) (newline)) m) (display "")) (define (rem-dup L) (foldl (λ (e res) (if (not (member e res)) (cons e res) res )) '() L )) (rem-dup '(1 1 3 2 3 4 2 5 3 6)) (display '::::::::::::::::::::::::::::::::::CURRY-UNCURRY)(newline) ; named let ;(let nume ((arg1 val-init1) (arg2 val-init2) ..) ; ... (nume )) ;(nume val-init1 val-init2 ..) ; efect named let (define (curry f NTotal) (let c-R ((N NTotal) (args '())) (if (zero? N) ; am transmis ultimul argument -> aplicăm funcția (apply f (reverse args)) ; altfel, întoarcem o funcție care mai are de luat N-1 argumente, ; reținem argumentul care s-a dat (λ (arg) (c-R (- N 1) (cons arg args)))) )) ((((curry + 3) 1) 2) 3) (define (uncurry f) (λ args (foldl (λ (arg fp) (fp arg)) f args)) ) ;; transformăm map în funcție curry (((((curry map 4) list) '(1 2 3)) '(a b c)) '(X Y Z)) ;; testăm uncurry ((uncurry (curry map 4)) list '(1 2 3) '(a b c) '(X Y Z)) ; transpunem matricea, folosind curry-map ; vom avea nevoie să inversăm apply ca să primească întâi elementul de listă și apoi funcția (define (flip f) (λ (x y) (f y x))) ; închidem fiecare rând din matrice într-o listă, ca să fie corect primit de apply (foldl (flip apply) ((curry map (+ (length M) 1)) list) (map list M)) (display '::::::::::::::::::::::::::::::::::PERMUTĂRI)(newline) ; (range 4) -> '(0 1 2 3 4) (define (range N) (if (zero? N) '(0) (append (range (- N 1)) (list N)))) ; ((split '(a b c d e)) 2) -> '((a b) c (d e)) (define (split L) (λ (idx) (let rec ((i idx) (Rest L) (Acc '())) (if (zero? i) (list (reverse Acc) (car Rest) (cdr Rest)) (rec (- i 1) (cdr Rest) (cons (car Rest) Acc)) )))) ; permutări cu funcționale (define (perms L) (if (<= (length L) 1) (list L) ; întorc o listă de permutări (apply append (map ; rezultă o listă de liste de permutări, le concatenez (λ (spl) (map (λ (LP) (cons (second spl) LP)) ; pentru fiecare împărțire, adaug elementul izolat ; la fiecare dintre permutările retului listei (perms (append (first spl) (third spl))))) (map (split L) (range (- (length L) 1))))))) ; generez toate împărțirile listei (perms '(1 2 3)) ; permutări cu backtracking (define (perms2 L) (let rec ((SolPart '())) ; named let (if (= (length SolPart) (length L)) (list SolPart) ; întorc o listă de soluții (apply append (map ; concatenez listele de soluții pentru fiecare variantă (λ (e) ; fiecare element din lista inițială e o variantă (if (member e SolPart) ; dacă nu e deja parte din soluție '() (rec (cons e SolPart)) ; adaug elementul la soluția parțială și continui recursiv )) L))))) (perms2 '(1 2 3)) (display '::::::::::::::::::::::::::::::::::ARBORI)(newline) (define TREE '(8 3 10 1 6 #f 14)) ; (3 1 6) (10 #f 14) (define root car) (define (left idx) (+ (* 2 idx) 1)) (define (right idx) (+ (* 2 idx) 2)) (define (branches tree) (map (λ (child) (map (λ (idx) (list-ref tree idx)) (let build-indexes ((L (list child))) (cond ((null? L) '()) ((>= (car L) (length tree)) (build-indexes (cdr L))) (else (cons (car L) (build-indexes (append (cdr L) (list (left (car L)) (right (car L))))))) ))) ) '(1 2) )) (define (display-tree tree . indent) ; număr variabil de argumente, primesc indent ca o listă (map display indent) (if (null? tree) (display "-\n") (let ((branches (branches tree)) (root (car tree))) (display root) (newline) (when (not (null? (filter (λ (br) (not (null? (filter identity br)))) branches))) (map (λ (br) (apply display-tree (cons br (cons " " indent)))) branches) (display "") )))) ; indexul din listă unde este (sau ar trebui să fie) un nod cu valoarea search (define (get-index tree search) (let rec ((tree tree) (search search) (c-index 0)) (let ((branch (branches tree)) (root (car tree))) (cond ((not root) c-index) ((equal? root search) c-index) ((< search root) (rec (first branch) search (left c-index))) (else (rec (second branch) search (right c-index))) )))) ; adaugă un nivel de frunze #f la arbore (define (extend tree) (if (not (null? (filter identity (drop tree (quotient (length tree) 2))))) (append tree (build-list (add1 (length tree)) (λ (x) #f))) tree)) ; dezasamblez lista la indexul respectiv, apoi o reasamblez, cu noua valoare (folosesc take și drop) (define (set-node tree index value) (append (take tree index) (list value) (drop tree (add1 index)))) ; extind dacă este nevoie, apoi adaug în locul unde trebuie să fie valoarea respectivă (define (add-node tree value) (let* ((Xtree (extend tree)) (index (get-index Xtree value)) (Usetree (if (> index (length tree)) Xtree tree)) ) (set-node Usetree index value))) TREE (extend (extend TREE)) (add-node TREE 9) (add-node (add-node TREE 11) 9) (add-node TREE 15) (display-tree TREE)