Jean-Jacques BOURDIN
Premier semestre 2019-2020
Le dernier partiel écrit aura lieu le 2/9/2020 en amphi B1. Entre 11 et 13h.
Tout étudiant qui n'a pas encore rendu son propre projet doit prendre contact au plus vite avec l'enseignant sauf à accepter d'être compté absent.
À partir du 19 août, 14h, de nouvelles séances de révision seront données sur le serveur Discord (ou sur un BBB). Les liens seront donnés sur cette page.
Dans tous les cas je reste disponible par mail pour toute question.
Une note va donc être affichée sur votre ENT. Elle tient compte de votre second partiel pour ceux qui l'ont passé ou simplement du premier.
Dans tous les cas, il sera possible de passer un "second partiel" à la fin des cours de second semestre, à une date que nous fixerons via un sondage en ligne.
Puisqu'il ne sera pas possible de faire un partiel en mai, ni juin, je vous propose deux modalités à choisir :
Dans la fenêtre du haut tapez "#lang racket" si ce n'est pas déjà affiché et ne faites plus rien dans cette fenêtre.
Ensuite, dans la fenêtre du bas, vous avez un "prompt" (>) et pouvez commencer à travailler.
Pour écrire votre programme, vous devriez utiliser emacs, qui va vous servir pour beaucoup d'autres choses.
Vous vous contentez de taper, dans un terminal, la commande
emacs exo1.l &Vous pouvez trouver des raccourcis claviers pour emacs sur ma page : ICI . Quand tout fonctionne bien, envoyez votre travail par mail: Utilisez, s'il vous plait, votre adresse mail donnée par l'université. Sinon, parfois, ma réponse ne vous parvient pas.
Mon adresse : jj
à : ai.univ-paris8.fr
(fct par81 par82 ... par_n)
(define (carre n) (* n n)) (define (negatif n) (if (< n 0) #t #f)) (define (plpt2 a b) (if (< a b) a b)))
Est récursif tout ce qui est récursif
(define (s n) (if (= n 0) 0 (+ (s (- n 1)) n)))
f(0)=1 |
f(1)=1 |
f(n)= f(n-1) + f(n-2) |
(define (pcr n) (if (< n 2) 1 (+ (pcr (- n 1)) (pcr (- n 2))))) |
(define (srt n) (srt_aux n 0)) (define (srt_aux n a) (if (= n 0) a (srt_aux (- n 1) (+ n a)))) |
(define (f n) (f2 n 1)) (define (f2 n a) (if (< n 2) a (f2 (- n 1) (* n a)))) |
>(cons 3 (cons 2 ())) = (3 2)
(car (cdr (cons 4 (cons 3 (cons 2 ()))))) 3
Mais c'est fatiguant d'écrire cette série de cons. Nous les remplaçons par une apostrophe :
(car (cdr '(4 3 2))Quand on a un objet, comment savoir si c'est une liste ? Si c'est une liste non vide, c'est une "paire".
> (pair? 2) #f > (pair? '(5 6)) #t > (pair? '()) #f >Les cinq fonctions indispensables sont donc :
(define (premierl l) (if (pair? l) (car l) '())) ; Combien cette liste a-t-elle d'éléments ? (define (nbele l) (if (pair? l) (+ 1 (nbele (cdr l))) 0)) ; Quelle est la somme de ses éléments ? (define (soml l) (if (pair? l) (+ (car l) (soml (cdr l))) 0)) |
(define (estvide l) (if (pair? l) #f #t)) |
(define (concat l1 l2) (if (estvide l1) l2 (cons (car l1) (concat (cdr l1) l2)))) |
(define (appartient m l) (if (pair? l) (if (= m (car l)) #t (appartient m (cdr l))) #f)) |
(define (belongs x l) (if (not (pair? l)) #f (if (= x (car l)) #t (belongs x (cdr l))))) |
(define (plgd2 a b) (if (< a b) b a)) (define (plgdl l) (plgdl_aux (cdr l) (car l))) (define (plgdl_aux l cand) (if (pair? l) (plgdl_aux (cdr l) (plgd2 cand (car l))) cand)) |
> (enlever 5 '(8 9 2 3 5 6 1 7)) '(8 9 2 3 6 1 7)
> (etlo 5 '(8 9 2 5 3 5 6 1 5 7)) '(8 9 2 3 6 1 7)
> (etloslp 5 '(8 9 2 5 3 5 6 1 5 7)) '(8 9 2 5 3 6 1 7))
Qui fabrique une liste de toutes les valeurs présentes au moins une fois dans la liste (i.e. sans répétition).
(define (conca l1 l2) (if (pair? l1) (cons (car l1) (conca (cdr l1) l2)) l2)) ;> ll ;'(8 1 2 8 1 9 2 10 3 4 7 5 6 12 13 -1 7) ;> (conca ll ll) ;'(8 1 2 8 1 9 2 10 3 4 7 5 6 12 13 -1 7 8 1 2 8 1 9 2 10 3 4 7 5 6 12 13 -1 7) |
(de (reve l) (if (not (pair? l)) l (if (not (pair? (cdr l))) l (cons (car (reve (cdr l))) (reve (cons (car l) (reve (cdr (reve (cdr l)))))))))) |
C'est ce qu'on appelle le tri par insertion.
(define (ins a lt) (if (pair? lt) (if (< a (car lt)) (cons a lt) (cons (car lt) (ins a (cdr lt)))) (list a))) |
Principe : on prend un élément de la liste, nommé le pivot, par exemple le premier. On fait deux sous-listes avec ceux qui sont plus grands, d'une part, plus petits de l'autre, que le pivot. Il ne reste plus qu'à trier ces deux listes indépendamment et à recoller les trois morceaux. Vous le faites au plus vite.
let et letrec(define (foct n m) (if (= n 0) m (let ((a (- n 1)) (b (+ m 1))) (foct a b)))) |
(define (fff) (load "Prog/Lisp/quic.l")) (define (estvide l) (if (pair? l) #f #t)) (define (concat l1 l2) (if (estvide l1) l2 (cons (car l1) (concat (cdr l1) l2)))) (define (range2 l) (if (< (car (cdr l)) (car l)) (cons (cadr l) (cons (car l) '())) l)) (define (qs l) (if (estvide l) l (if (estvide (cdr l)) l (if (estvide (cddr l)) (range2 l) (qs_aux (car l) (separe (car l) (cdr l) '() '())))))) (define (qs_aux pivot deuxlistes) (concat (qs (car deuxlistes)) (cons pivot (cadr deuxlistes)))) (define (separe pivot l lpt lgd) (if (estvide l) (cons lpt (cons lgd '())) (if (< (car l) pivot) (separe pivot (cdr l) (cons (car l) lpt) lgd) (separe pivot (cdr l) lpt (cons (car l) lgd))))) |
(define (qs3 l) (if (unpair l) '() (if (unpair (cdr l)) l (if (unpair (cddr l)) (range2 l) (let ((deuxl (separe (car l) (cdr l)))) (let ((petits (qs3 (car deuxl))) (grands (qs3 (cdr deuxl)))) (concat petits (cons (car l) grands)))))))) ;> (qs3 '(9 8 2 7 1 10 12 6 5 23 31 14 15 -1 6 5)) .'(-1 1 2 5 5 6 6 7 8 9 10 12 14 15 23 31) |
(define (qs3 l) (if (unpair l) '() (if (unpair (cdr l)) l (if (unpair (cddr l)) (range2 l) (letrec ((deuxl (separe (car l) (cdr l))) (petits (qs3 (car deuxl))) (grands (qs3 (cdr deuxl)))) (concat petits (cons (car l) grands))))))) ;> (qs3 '(9 8 2 7 1 10 12 6 5 23 31 14 15 -1 6 5)) .'(-1 1 2 5 5 6 6 7 8 9 10 12 14 15 23 31) |
La quote permet de ne pas évaluer.
La backquote permet de ne pas évaluer sauf si on trouve une virgule.
`(1 2 3 ,(+ 4 5)) vaut '(1 2 3 9)
(define (concat2 la lb) `(,@la ,@lb)) |
(define (fibcond n) (cond ((= n 0) 1) ((= n 1) 1) (else (+ (fibcond (- n 1)) (fibcond (- n 2)))))) (define (fibcase n) (case n ((0) 1) ((1) 1) (else (+ (fibcase (- n 1)) (fibcase (- n 2)))))) ;> (fibcase 5) ;8 ;> (fibcase 6) ;13 ;> (fibcond 5) ;8 ;> (fibcond 6) ;13 |
(define (carre n) (* n n)) (define (funcall fct liste) (if (unpair liste) '() (cons (fct (car liste)) (funcall fct (cdr liste))))) ;> (funcall carre '(7 8 1 2 9 3 8 11 0)) ;'(49 64 1 4 81 9 64 121 0) |
Il vous reste à faire la fonction qui prend un premier paramètre, la fonction à appliquer, par exemple carre, et un deuxième paramètre, la liste et qui renvoie la somme des carrés de tous les éléments de la liste. Mais avec comme paramètre cube, c'est la somme des cubes...
Mais, et si on change l'opération ? Si on passe à la multiplication par exemple ? Il faut dans ce cas appliquer ce nouveau paramètre. Écrivez la fonction muchfun :
;> (muchfun + carre '( 1 2 3 0)) ;= 14 |
(define (liste? (l) (if (unpair l) #f (if (equal? l '()) #t (liste? (cdr l))))) |
; (define (appartient x l) (if (unpair l) #f (if (pair? (car l)) (if (appartient x (car l)) #t (appartient x (cdr l))) (if (equal? x (car l)) #t (appartient x (cdr l)))))) ;> (appartient 5 '((1 (2) (3 4 5 () 6)) (a b c))) ;#t ;> (appartient 'a '((1 (2) (3 4 5 () 6)) (a b c))) ;#t ;> (appartient 'b '((1 (2) (3 4 5 () 6)) (a b c))) ;#t ;> (appartient 'e '((1 (2) (3 4 5 () 6)) (a b c))) ;#f |
Notons que "equal?" sert à tester l'egalite quand il ne s'agit pas de nombres.
(define (cher x l) (if (unpair l) #f (if (pair? (car l)) (if (cher x (car l)) #t (cher x (cdr l))) (if (equal? x (car l)) #t (cher x (cdr l)))))) |
Ensuite regardons la somme des éléments numériques d'une liste :
(define (unpair l) (not (pair? l))) (define (somlc l) (if (unpair l) 0 (if (pair? (car l)) (+ (somlc (car l)) (somlc (cdr l))) (if (equal? (car l) '()) (somlc (cdr l)) (+ (car l) (somlc (cdr l))))))) |
(cadar (cddr '(1 (2) (3 4 5 () 6)))) (caddr (cddr '(1 (2) (3) (4 5 () 6)))) (cddr '(1 (2) (3) (4 5 () 6))) (caddr (cddr '(1 (2) (3) (4 5 () 6)))) (caaar '((1 (2) (3 4 5 () 6) (a b c) (d)))) (cadar (cddar '((1 (2) (3 4 5 () 6)) (a b c)))) (caddr (cddar '((1 (2) (3 4 5 () 6)) (a b c)))) (caddr (cddar '((1 (2) (3 4 5 () 6)) (a b c) (d)))) (caddr (cddar '((1 (2) (3 4 5 () 6) (a b c) (d))))) (cddar '((1 (2) (3 4 5 () 6) (a b c) (d)))) |
Quelques exemples :
(define (ee) (load "Prog/Lisp/gra.l")) (require graphics/graphics) ;La fonction suivante n est pas utlisee (define (dessine_sur port) ((draw-line port) (make-posn 30 30) (make-posn 100 100)) ((draw-line port) (make-posn 100 100) (make-posn 170 30)) ((draw-ellipse port) (make-posn 50 50) 100 100) ((draw-ellipse port) (make-posn 100 90) 100 200 "red") ((draw-solid-ellipse port) (make-posn 50 100) 30 20 "cyan") ) (define (findes port) (close-viewport port) ; viewport disappears (close-graphics) ; again, nothing appears to happen, but ; unclosed viewports (if any) would disappear ) (define (dessine_vis port) ; make-posn fabrique une position a partir des deux coordonnees ((draw-polygon port) (list (make-posn -120 -120)(make-posn 120 -120)(make-posn 120 120)(make-posn -120 120)) (make-posn 140 130)) ((draw-ellipse port) (make-posn 50 30) 150 180) ((draw-ellipse port) (make-posn 70 90) 45 20 "magenta") ((draw-solid-ellipse port) (make-posn 80 90) 15 15 "blue") ((draw-ellipse port) (make-posn 130 90) 45 20 "magenta") ((draw-solid-ellipse port) (make-posn 140 90) 15 15 "blue") ((draw-line port) (make-posn 90 160) (make-posn 150 160) "red") ((draw-line port) (make-posn 120 100) (make-posn 120 150)) ) (define (face) (open-graphics) ; nothing appears to happen, but the library is initialized... (define viz (open-viewport "visage" 300 300)) (dessine_vis viz) ; attendre un peu pour voir l image (sleep 20) (findes viz) ) |
'() '(8 (5 () ()) (9 () (11 () ())))sont des listes rangées Chercher un élément dans une telle liste est rapide, il suffit de savoir où chercher.
(define (yest x lr) (if (estvide lr) #f (if (= x (car lr)) #t (if (< x (car lr)) (yest x (cadr lr)) (yest x (caddr lr)))))) |
(define (unpair l) (if (pair? l) #f #t)) (define (petits a l) (if (unpair l) '() (if (< a (car l)) (petits a (cdr l)) (cons (car l) (petits a (cdr l)))))) (define (grands a l) (if (unpair l) '() (if (> a (car l)) (grands a (cdr l)) (cons (car l) (grands a (cdr l)))))) (define (range4 l) (if (< (car l) (cadr l)) `(,(car l) () (,(cadr l) () ())) `(,(car l) (,(cadr l) () ()) ()))) (define (qsl l) (if (unpair l) l (if (unpair (cdr l)) `(,(car l) () ()) (if (unpair (cddr l)) (range4 l) `( ,(car l) ,(qsl (petits (car l) (cdr l))) ,(qsl (grands (car l) (cdr l)))))))) |
(define (separe pivot l) (separ pivot l '() '())) (define (separ pivot l ptl gdl) (if (unpair l) `(,ptl ,gdl) (if (< (car l) pivot) (separ pivot (cdr l) (cons (car l) ptl) gdl) (separ pivot (cdr l) ptl (cons (car l) gdl))))) (define (tsl l) (if (unpair l) l (if (unpair (cdr l)) `(,(car l) () ()) (if (unpair (cddr l)) (range4 l) (let* ((sep (separe (car l) (cdr l))) (pts (tsl (car sep))) (gds (tsl (cadr sep)))) `(,(car l) ,pts ,gds)))))) |
(define (okgd pivot lr) (if (unpair lr) #t (if (< pivot (car lr)) #f (if (okgd pivot (cadr lr)) (okgd pivot (caddr lr)) #f)))) (define (okpt pivot lr) (if (unpair lr) #t (if (> pivot (car lr)) #f (if (okpt pivot (cadr lr)) (okpt pivot (caddr lr)) #f)))) (define (estlr lr) (if (unpair lr) (if (equal? lr '()) #t #f) (if (okgd (car lr) (cadr lr)) (if (okpt (car lr) (caddr lr)) (if (estlr (cadr lr)) (estlr (caddr lr)) #f) #f) #f))) |
Les listes d'association sont des listes de couples (a b) où a est
un "identifiant" et b est la valeur associée. Par exemple:
((couleur rouge) (taille grande) (forme cube))
On peut utiliser la fonction assoc ou définir la
fonction asso qui permettent, pour un
certain identifiant de déterminer la valeur associée.
(define (asso n la) (if (estvide la) la (if (= (caar la) n) (cadar la) (asso n (cdr la))))) |
;? al ;=((0 0) (1 1) (2 4) (3 9) (4 16) (5 25) (6 36)) ;? (assoc 4 al) ;= (4 16) ;? (car (assoc 4 al)) ;= 4 ;? (cdr (assoc 4 al)) ;= 16 |
(define (creerla l1 l2) (if (estvide l1) l1 (if (estvide l2) l2 (cons `(,(car l1) ,(car l2)) (creerla (cdr l1) (cdr l2)))))) (define (creerlaf l fct) (if (estvide l) l (cons `(,(car l) ,(fct (car l))) (creerlaf (cdr l) fct)))) |
Un exemple d'utilisation du "cond".
(define (lecond n) (cond ((= n 0) 1) ((= n 1) 1) (* (+ (lecond (- n 1)) (lecond (- n 2)))))) |
; Une fonction classique pour commencer (define (unpair l) (not (pair? l))) ; Deux exemples pour voir comment seront présentées les "fonctions-listes" (define deffct1 '(define (fct1 x) (+ x (* x x)))) (eval deffct1) (define deffct2 '(define (fct2 x) (* (+ x 5) (+ x 5)))) (eval deffct2) |
;> (eval deffct1) ;> (fct1 5) ;30 |
(define (fact n) (if (= n 0) 1 (* n (fact (- n 2))))) (define (som n) (if (= n 0) 0 (+ n (som (- n 2))))) |
(define (faitfct nom oper neutre para) (list 'define (list nom para) `(if (= ,para 0) ,neutre ,(list oper para (list nom `(- ,para 1)))))) ;> (faitfct 'fact '* 1 'n) ;'(define (fact n) (if (= n 0) 1 (* n (fact (- n 1))))) ;> (eval (faitfct 'fact '* 1 'n)) ;> (fact 5) ;120 ;> |
(define (hh) (load "Prog/Lisp/hanoi.l")) (define (affiche n dep arr) (printf "~a de ~a a ~a\n" n dep arr)) ;; plus joli comme affichage, non ? (define (exaffiche n dep arr) (print n) (print " ") (print dep) (write " a ") (writeln arr)) (define (hanoi n dep arr tmp) (if (= n 1) (affiche 1 dep arr) (begin (hanoi (- n 1) dep tmp arr) (affiche n dep arr) (hanoi (- n 1) tmp arr dep)))) ;; > (hanoi 5 'triangle 'carre 'rond) ;; 1 de triangle a carre ;; 2 de triangle a rond ;; 1 de carre a rond ;; 3 de triangle a carre ;; 1 de rond a triangle ;; 2 de rond a carre ;; 1 de triangle a carre ;; 4 de triangle a rond ;; 1 de carre a rond ;; 2 de carre a triangle ;; 1 de rond a triangle ;; 3 de carre a rond ;; 1 de triangle a carre ;; 2 de triangle a rond ;; 1 de carre a rond ;; 5 de triangle a carre ;; 1 de rond a triangle ;; 2 de rond a carre ;; 1 de triangle a carre ;; 3 de rond a triangle ;; 1 de carre a rond ;; 2 de carre a triangle ;; 1 de rond a triangle ;; 4 de rond a carre ;; 1 de triangle a carre ;; 2 de triangle a rond ;; 1 de carre a rond ;; 3 de triangle a carre ;; 1 de rond a triangle ;; 2 de rond a carre ;; 1 de triangle a carre |
(define (frfr) (load "Prog/Lisp/sierp.l")) (require 2htdp/image) (define (sierpinski0 d) (triangle d 'solid 'black)) (define (sierpinski n d) (if(= n 0) (sierpinski0 d) (above (sierpinski (- n 1) d) (beside (sierpinski (- n 1) d) (sierpinski (- n 1) d)) ))) (define (tryit) (sierpinski 5 10)) (define (essai) (beside/align "bottom" (sierpinski 0 20) (sierpinski 1 20) (sierpinski 2 20) (sierpinski 3 20) (sierpinski 4 20)) (beside (sierpinski 3 40) (sierpinski 4 20) (sierpinski 5 10))) |
(define A 6) ; vous connaissez (define (plgd2 a b) (if (< a b) b a)) (define (gdpl a b) ((lambda (x y) (if (< x y) y x)) a b)) (define (f x y) (if (= x y) x (if (< x y) (f x (- y x)) (f (- x y) y)))) (define (g x y) ((lambda (x y) (if (= x y) x (if (< x y) (g x (- y x)) (g (- x y) y)))) x y)) |
(define (fib) (fibrt (read))) (define (fibrt n) (fibrtaux n 2 1 1)) (define (fibrtaux n i pred ante) (if (< n i) pred (fibrtaux n (+ i 1) (+ pred ante) pred))) |
Dernière mise à jour de ce document :