#lang racket ; ------------------Funcții ca valori evaluate la ele însele------------------ (define a +) ;a ;(a 2 3 5) ;null? (define fs (list + (λ (x y) (- x y y)) ((λ (x) (λ (y) (- x y y))) 5) ; (λ (y) (- 5 y y)) 5)) ;fs ;((cadr fs) 20 8) ;((caddr fs) 1) ; ------------------Funcții ca valori de retur------------------ (define (f x) (if (< x 100) + -)) ;(f 25) ;((f 120) 16 4) (define (g x) (λ (y) ; y = (cons x y))) ; x = ;(g 2) ; x=2 retur=(λ (y) (cons 2 y) ;( (g 2) '(5 2) ) ; y='(5 2) retur=(cons 2 '(5 2))='(2 5 2) ;---------------------- curry / uncurry (define (plus-curry x) (λ (y) ; (λ (y) (+ 1 y)) (+ x y ))) ; (define (plus-uncurry x y) (+ x y)) ; identic cu (define plus-uncurry +) ; Cum adun 2+4? ;( (plus-curry 2) 4 ) ;(plus-uncurry 2 4) ; Ce se întâmplă la aplicare parțială? ;(plus-curry 2) - o funcție ;(plus-uncurry 2) - eroare ; Cum obțin (cu efort minim) inc din plus? (define inc-curry (plus-curry 1)) ;alternativa lungă: (define (inc-curry x) ((plus-curry 1) x)) ;în loc să scriu f(x)=g(x) am scris f = g ;(inc-curry 5) (define (inc-uncurry x) (plus-uncurry 1 x)) ;(inc-uncurry 5) ; Pt a incrementa toate valorile dintr-o listă: ;(define L '(1 2 3 4 5)) ;(map (λ (x) (+ x 1)) L) ;(map (plus-curry 1) L) ; există în Racket mecanismul de a transforma o funcție uncurry in varianta ei curry ;(map ((curry +) 1) L) ; ------------------Reutilizare de cod------------------ ; inseram primul element din lista in ; sortarea recursiva a restului listei (define (ins-sort op) (λ (L) (if (null? L) L (insert op (car L) ((ins-sort op) (cdr L)))))) (define (insert op x S) (if (or (null? S) (op x (car S))) (cons x S) (cons (car S) (insert op x (cdr S))))) (define sort< (ins-sort <)); scriem minim posibil (aplicare partiala) ;(sort< '(2 6 3 5 2 1 2 1 0)) ; varianta "lungă": (define (sort< L) ((ins-sort <) L)) ; în loc de (f x) = (g x), scriu f = g, ceea ce e mai succint (define sort> (ins-sort >)) ;sort< ;(sort< '(5 3 1 4)) ;(sort> '(5 3 1 4)) ; intoarce lista in care toate parele au fost transformate si imparele au ramas la fel ;(define (transform-evens f L) ; f = transformarea ; (cond ((null? L) L) ; ((even? (car L)) (cons (f (car L)) (transform-evens f (cdr L)))) ; (else (cons (car L) (transform-evens f (cdr L)))))) ; ;(transform-evens inc-curry '(1 2 3 5 6)) ; ;(define (transform-odds f L) ; (cond ((null? L) L) ; ((odd? (car L)) (cons (f (car L)) (transform-odds f (cdr L)))) ; (else (cons (car L) (transform-odds f (cdr L)))))) ;(transform-odds inc-curry '(1 2 3 5 6)) ; Să observăm șablonul comun și să abstractizăm funcția: (define (transform-pred pred?) (λ (f L) (cond ((null? L) L) ((pred? (car L)) (cons (f (car L)) ((transform-pred pred?) f (cdr L)))) (else (cons (car L) ((transform-pred pred?) f (cdr L))))))) ; Cum obținem cele 2 funcții din funcția mai generală? (define transform-evens (transform-pred even?)) (define transform-odds (transform-pred odd?)) ;(transform-evens ((curry cons) 1) '(1 2 3 5 6)) ;(transform-odds inc-curry '(1 2 3 5 6)) ; sa sortez descrescator listele interioare ;(define L '(1 2 (3 6 4) (5 1 1 3 0) 6 7 (2 2 3))) ;((transform-pred list?) sort> L) ; ------------------Șabloane comune------------------ (define (sum-series start stop term next) ; next=functie care imi spune cum trec de la i la urm i ; term=functie care imi calculeaza termenul curent in fctie de i (if (> start stop) 0 (+ (term start) (sum-series (next start) stop term next)))) (define (sum-interval a b) (if (> a b) 0 (+ a (sum-interval (add1 a) b)))) ;(sum-interval 1 10) (define (ex1 a b) (sum-series a b (λ (x) x) add1)) ;(ex1 1 10) ; e = 1/0! + 1/1! + 1/2! + 1/3! + ... (define (sum-e n) (define (iter i) (if (> i n) 0 (+ (/ 1. (factorial i)) (iter (+ i 1))))) (iter 0)) (define (ex2 n) (sum-series 0 n (λ (x) (/ 1. (factorial x))) add1)) ; de implementat ulterior cu funcționale ; (range x y) = (x x+1 x+2 .. y-1) (define (factorial n) (define (fact-tail n acc) (if (zero? n) acc (fact-tail (sub1 n) (* n acc)))) (fact-tail n 1)) ;(map factorial (range 1 10)) ;(sum-e 15) ;(ex2 15) ; π^2/8 = 1/1^2 + 1/3^2 + 1/5^2 + ... (define (sum-pi2/8 n) (define (iter i) (if (> i (* 2 n)) 0 (+ (/ 1. (sqr i)) (iter (+ i 2))))) (iter 1)) ;(sqrt (* 8 (sum-pi2/8 711111))) (define (ex3 n) (sum-series 1 (* 2 n) (λ (x) (/ 1. (sqr x))) (compose add1 add1))) ;(sqrt (* 8 (ex3 711111))) ; ------------------Funcționale------------------ ;; Maximul elementelor dintr-o listă de numere (define (max-list L) (if (null? L) -inf.0 (max (car L) (max-list (cdr L))))) ;(max-list '(5 2 1 4 11 5 7 5 7 3)) (define (max-list-f L) (foldl max -inf.0 L)) ;(max-list-f '(5 2 1 4 11 5 7 5 7 3)) ;; Extragerea inițialelor dintr-o listă de nume (define (initials names) (if (null? names) '() (cons (substring (car names) 0 1) (initials (cdr names))))) ;(initials '("Winston" "Leonard" "Spencer" "Churchill")) (define (initials-f names) (map (λ (name) (substring name 0 1)) names)) ;(initials-f '("Winston" "Leonard" "Spencer" "Churchill")) ;; Extragerea pronumelor dintr-o listă de cuvinte (define (pronouns words) (cond ((null? words) '()) ((member (car words) '(I you he she we they)) (cons (car words) (pronouns (cdr words)))) (else (pronouns (cdr words))))) (define YS '(In the town where I was born Lived a man who sailed to sea And he told us of his life In the land of submarines So we sailed up to the sun 'Til we found a sea of green And we lived beneath the waves In our yellow submarine)) ;(pronouns YS) (define (pronouns-f words) (filter (λ (word) (member word '(I you he she we they))) words)) ;(pronouns-f YS) (define (pronouns-fold words) (foldr (λ (word acc) (if (member word '(I you he she we they)) (cons word acc) acc)) '() words)) ;(pronouns-fold YS) ;; Pătratele elementelor dintr-o listă de numere (define (squares L) (if (null? L) L (cons (sqr (car L)) (squares (cdr L))))) ;(squares '(1 2 3)) (define (squares-f L) (map sqr L)) ;(squares-f '(1 2 3)) ;; Numărul de elemente impare dintr-o listă (define (count-odds L) (if (null? L) 0 (+ (if (odd? (car L)) 1 0) (count-odds (cdr L))))) ;(count-odds '(1 2 3)) (define (count-odds-f L) (foldr (λ (elem acc) (if (odd? elem) (add1 acc) acc)) 0 L)) ;(count-odds-f '(1 2 3 5 5 6 7 9 11 13)) (define (count-odds-filter L) (length (filter odd? L))) ;(count-odds-filter '(1 2 3 5 5 6 7 9 11 13)) ;; Extragerea numerelor unei liste care sunt mai mici decât o valoare dată (define (smaller-than x L) (cond ((null? L) L) ((< (car L) x) (cons (car L) (smaller-than x (cdr L)))) (else (smaller-than x (cdr L))))) ;(smaller-than 3 '(1 2 3)) (define (smaller-than-f x L) (filter ((curry >) x) L)) ; (filter (λ (elem) (< elem x)) L)) ;(smaller-than-f 3 '(1 2 3 4 1 3 2)) ;---------------------- Implementare map și filter folosind fold (define (my-map f L) (foldr (λ (x acc) (cons (f x) acc)) '() L)) ;(my-map add1 '(1 2 3 4 5)) (define (my-filter p L) (foldr (λ (x acc) (if (p x) (cons x acc) acc)) '() L)) ;(my-filter odd? '(1 2 3 4 5)) ;---------------------- TDA-uri (define make-complex list) (define real car) (define imag cadr) (define (add-c C1 C2) (make-complex (+ (real C1) (real C2)) (+ (imag C1) (imag C2)))) ;(add-c (make-complex -1 2) (make-complex 4 1)) ;Constructori ; empty-bst : -> BST ; make-bst : BST x Elem x BST -> BST (define empty-bst '()) (define make-bst list) ;Operatori ; left : BST -> BST ; right : BST -> BST ; key : BST -> Elem ; bst-empty? : BST -> Bool ; insert-bst : Elem x BST -> BST ; list->bst : List -> BST (define left first) (define right third) (define key second) (define bst-empty? null?) (define (insert-bst x bst) (cond ((bst-empty? bst) (make-bst empty-bst x empty-bst)) ((< x (key bst)) (make-bst (insert-bst x (left bst)) (key bst) (right bst))) (else (make-bst (left bst) (key bst) (insert-bst x (right bst)))))) (define (list->bst L) (foldl insert-bst empty-bst L)) ;(list->bst '(3 6 1 2 4 8)) ;'((() 1 (() 2 ())) 3 ((() 4 ()) 6 (() 8 ())))