#lang racket (require "utils.rkt") ;------------------Soluție naivă----------------------- #| ; fibonacci recursiv pur (define (fib n) (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2))))) ; soluție modulară, elegantă (define (average-even-fibs n) (let* ((interval (range n)) (fibs (map fib interval)) (even-fibs (filter even? fibs)) (sum (apply + even-fibs)) (len (length even-fibs))) (if (zero? len) 0 (/ sum len)))) (average-even-fibs 10) (average-even-fibs 39) ; 0 1 1 2 3 5 8 13 21 34 |# ;------------------Cu optimizările propuse----------------------- #| (define (fib n) (let loop ((n n) (a 0) (b 1)) (if (zero? n) a (loop (- n 1) b (+ a b))))) (define (average-even-fibs n) (average-even-fibs 10) (time (average-even-fibs 5000)) |# ;------------------Cu fluxuri----------------------- #| (define fib-stream (let loop ((a 0) (b 1)) (stream-cons a (loop b (+ a b))))) ; Abstractizăm funcția average, ; restaurând expresivitatea funcției principale (define (average s) (match-let (((list sum len) (stream-fold (λ (acc x) (list (+ x (car acc)) (+ 1 (cadr acc)))) '(0 0) s))) (if (zero? len) 0 (/ sum len)))) (define (average-even-fibs n) (average-even-fibs 10) (time (average-even-fibs 5000)) |# ;------------------Cu memoizare----------------------- #| (define fib-cache (make-hash)) (define (fib n) (if (< n 2) n (hash-ref! fib-cache n (λ () (+ (fib (- n 1)) (fib (- n 2))))))) (define (average s) (match (stream-fold (λ (acc x) (list (+ x (car acc)) (+ 1 (cadr acc)))) '(0 0) s) ((list _ 0) 0) ((list sum len) (/ sum len)))) (define (stream-range a b) (if (= a b) empty-stream (stream-cons a (stream-range (add1 a) b)))) (define (average-even-fibs n) (average-even-fibs 10) (time (average-even-fibs 5000)) |# ;------------------Cu macro----------------------- #| (define/memo (fib n) (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2))))) (define (average s) (match (stream-fold (λ (acc x) (list (+ x (car acc)) (+ 1 (cadr acc)))) '(0 0) s) ((list _ 0) 0) ((list sum len) (/ sum len)))) (define (stream-range a b) (if (= a b) empty-stream (stream-cons a (stream-range (add1 a) b)))) (define (average-even-fibs n) (average (stream-filter even? (stream-map fib (stream-range 0 n))))) (average-even-fibs 10) (time (average-even-fibs 5000)) |# ;--------------Reutilizare macro------------------------ ; Ex: numărul minim de monede din setul coins ; cu care se poate plăti suma sum ;(define/memo (coin-change coins sum) ;(map (curry coin-change '(1 5 10 25)) (range 50 61)) ;-------------Programare simbolică---------------------- ; Transformarea în named let, pentru șablonul ;(define (f ...) ; (define (g ...) ; corp-g) ; (g ...)) #| (define (rewrite-to-named-let expr) (match expr |# (define code-fact '(define (fact n) (define (helper n acc) (if (zero? n) acc (helper (- n 1) (* n acc)))) (helper n 1))) (define code-fib '(define (fib n) (define (helper n a b) (if (zero? n) a (helper (- n 1) b (+ a b)))) (helper n 0 1))) ;(rewrite-to-named-let code-fact) ;(rewrite-to-named-let code-fib)