• Aucun résultat trouvé

TD n°8 - Correction

N/A
N/A
Protected

Academic year: 2022

Partager "TD n°8 - Correction"

Copied!
9
0
0

Texte intégral

(1)

TD n°8 - Correction

; TD n°8

(require (lib "trace.ss"))

(require racket/list) ; pour pouvoir utiliser la fonction flatten qui aplatit une liste .. sinon voir TD n°7

(define (fac n) (if (zero? n) 1

(* n (fac (sub1 n))))) (define (fac_term n)

(define (fac_it n acc) (if (zero? n)

acc

(fac_it (sub1 n) (* acc n)))) (fac_it n 1))

;(time (fac 10000))

;(time (void (fac 10000)))

;(time (void (fac 20000)))

;(time (void (fac 30000)))

;(time (void (fac 40000)))

(define chaine "ceci est une chaine de caractères")

(define liste '(ceci n'est pas une chaine de caractères))

; -attention au quote - si ce n'est une chaine mais alors qu'est ce que c'est ?

(define chaineenliste (string->list chaine))

(define listenenchaine (list->string chaineenliste))

;(define listenenchaine2 (list->string liste)) (define nombre 1515)

(define nombreenchaine (number->string nombre))

(define pieenchaine (number->string pi));évidemment DrRacket connaît Pi

;nombre

;pi

;nombreenchaine

;pieenchaine

;(+ pi nombre)

;(+ pieenchaine nombre)

;(+ nombreenchaine pieenchaine)

;(string-append nombreenchaine pieenchaine)

;(eqv? (cadr chaineenliste) #\E)

;(eqv? (cadr chaineenliste) #\e)

;1515

;3.141592653589793

;"1515"

;"3.141592653589793"

;1518.14159265359

;"15153.141592653589793"

;#f

;#t

(2)

(define (ordre_de_grandeur n)

(sub1 (string-length (number->string n))))

;(ordre_de_grandeur 1515)

;(ordre_de_grandeur (fac_term 5))

;(ordre_de_grandeur (fac_term 10000))

;3

;2

;35659

(define (ordre_de_grandeur2 n) (if (zero? (quotient n 10) ) 0

(+ 1 (ordre_de_grandeur2 (quotient n 10)))))

(define (ordre_de_grandeur_term n) (define (bosse_it n acc)

(if (zero? (quotient n 10) ) acc

(bosse_it (quotient n 10) ( + 1 acc)))) (bosse_it n 0))

;(ordre_de_grandeur_term 1515)

;(ordre_de_grandeur_term (fac_term 5))

;(ordre_de_grandeur_term (fac_term 10000))

;3

;2

;35659

; étude des réels

(define Avogadro 6.02e23) (define chargeelem 1.6e-19) (define (max_ordre_reel) (define (bosse_it val aux) (if (= val +inf.0)

aux

(bosse_it (* val 10) (+ 1 aux)))) (bosse_it 1.0 0))

(define (min_ordre_reel) (define (bosse_it val aux) (if (zero? val)

aux

(bosse_it (/ val 10) (sub1 aux)))) (bosse_it 1.0 0))

;> (max_ordre_reel)

;309

;> (min_ordre_reel)

;-324

(3)

; manipulations de listes

;utilistaire de création de liste d'entiers de 0 à n (define (cree_liste_integer0 n)

(if (zero? n) (list 0)

(cons n (cree_liste_integer (sub1 n)))))

; une version terminale

(define (cree_liste_integer n) (define (bosse n aux)

(if (zero? n) (cons 0 aux)

(bosse (sub1 n) (cons n aux)))) (bosse n '()))

;utilitaires de création de liste d'entiers relatifs aleatoires

;retourne une liste de n entiers déterminés de façon aléatoire dans l’intervalle [0 , n_max[

(define (cree_liste_random0 n n_max) (if (zero? n)

()

(cons (random n_max)

(cree_liste_random (sub1 n)n_max))))

; mieux en version terminale

(define (cree_liste_random_1 n n_max) (define (bosse n aux)

(if (zero? n) aux

(bosse (sub1 n) (cons (random n_max) aux)))) (bosse n '()))

;retourne une liste de n entiers déterminés de façon aléatoire dans l’intervalle ]- n_max , n_max[

(define (random_liste2_0 n n_max) (if (zero? n)

()

(cons (- (random (* 2 n_max))n_max ) (random_liste2 (sub1 n)n_max)))) (define (cree_liste_random n n_max)

(define (bosse n aux) (if (zero? n)

aux

(bosse (sub1 n) (cons (- (random (* 2 n_max))n_max ) aux)))) (bosse n '()))

; creation de quelques listes pour faire les tests des fonctions

(define lis1 (cree_liste_random 10 100)) ; creation d'une liste de 10 entiers relatifs compris entre -100 et 100

(display "liste 1 : ") (display lis1)

(newline)

(4)

(define lis2 (cree_liste_random 10 5)) ; entre -5 et 5 (display "liste 2 : ") ; liste plate

(display lis2) (newline)

;liste non plate uniquement formée de combinaisons de lis2 pour mieux suivre les résultats de fonctions

(define lis3 (cons (cons lis2 (reverse lis2)) (cons(reverse lis2) (cons lis2 '())))) (display "liste 3 : ") ; liste plate

(display lis3) (newline)

;liste non plate uniquement formée de combinaisons de lis1 et lis2 (define lis4 (cons (cons lis1 (reverse lis2))

(cons(reverse lis1) (cons lis2 '())))) (display "liste 4 : ") ; liste plate

(display lis4) (newline)

; le TD

;OCCURRENCE

(define (occurrence nb liste) (if (null? liste)

0

(+ (if (= nb (car liste)) 1

0)

(occurrence nb (cdr liste))))) ;(occurrence 3 lis2)

(define (occurrence_gene nb liste) (if (null? liste)

0

(+ (if (list? (car liste))

(occurrence_gene nb (car liste)) (if (= nb (car liste))

1 0))

(occurrence_gene nb (cdr liste)))))

;(occurrence_gene 3 lis3)

; dans les deux fonctions ci-dessus, le nombre nb est invariable à chaque appel récursif

;... et à chaque appel récursif, les appels emportent dans leur environnement une variable inutile puisque inchangée

;... et cela prend de la place en mémoire (dans la pile de gestion des appels récursifs)

; donc on peut écrire une fonction qui fait effectivement le travail voulu mais qui n'a pas nb en argument

(5)

(define (occurrence2 nb liste) (define (bosse liste)

(if (null? liste) 0

(+ (if (= nb (car liste)) 1

0)

(bosse (cdr liste))))) (bosse liste))

;pour les tests (occurrence 3 lis2) (occurrence2 3 lis2)

(define (occurrence_gene2 nb liste) (define (bosse liste)

(if (null? liste) 0

(+ (if (list? (car liste)) (bosse (car liste)) (if (= nb (car liste)) 1

0))

(bosse (cdr liste))))) (bosse liste))

;pour les tests (occurrence_gene 3 lis3) (occurrence_gene2 3 lis3)

; les fonctions suivantes sont écrites en respectant la même démarche : ; éviter les appels récursifs qui "trimbalent" des paramètres inchangés

;ENLEVE

(define (enleve nb liste) (define (bosse liste) (if (null? liste) ()

(if (= nb (car liste))

(bosse (cdr liste)) ; la recursion sur la queue n'est pas faite deux fois donc inutile d'utiliser un let

(cons (car liste) (bosse (cdr liste)))))) (bosse liste))

;(enleve 3 lis2)

(define (enleve_gene nb liste) (define (bosse liste)

(if (null? liste) ()

(if (list? (car liste))

(cons (bosse (car liste)) (bosse (cdr liste))) (if (= nb (car liste)) (bosse (cdr liste)) (cons (car liste)

(bosse (cdr liste))))))) (bosse liste))

(6)

;(enleve_gene 3 lis3)

;REMPLACE

(define (remplace nb_a_rem nb_rem liste)

; ici l'appel à bosse évite de "trimballer" deux variables dans les appels récursifs : nb_a_rem nb_rem

(define (bosse liste) (if (null? liste) ()

(if (= nb_a_rem (car liste))

(cons nb_rem (bosse (cdr liste))) ; la recursion sur la queue n'est pas faite deux fois donc inutile d'utiliser un let

(cons (car liste) (bosse (cdr liste)))))) (bosse liste))

; (remplace 3 'plouf lis2)

(define (remplace_gene nb_a_rem nb_rem liste) (define (bosse liste)

(if (null? liste) ()

(if (list? (car liste))

(cons (bosse (car liste)) (bosse (cdr liste))) (if (= nb_a_rem (car liste))

(cons nb_rem (bosse (cdr liste)))

(cons (car liste)(bosse (cdr liste))))))) (bosse liste))

;(remplace_gene 3 'plouf lis3)

;ELIMINE DOUBLON

(define (elimine_doublon liste)

(if( or (null? (cdr liste)) (null? liste)) liste

(cons (car liste) (elimine_doublon (enleve (car liste) (cdr liste))))))

;(elimine_doublon lis2)

; pour enlever les doublons dans une liste non plate c'est beaucoup plus compliqué !

; fonction auxiliaire qui enleve tous les élements d'une liste plate List1 dans une liste non plate liste

(define (enleve_gene_aux Liste1 liste) (if (null? Liste1)

liste

(enleve_gene_aux (cdr Liste1) (enleve_gene (car Liste1) liste))))

; fonction qui aplatit une liste prédéfinie flatten sinon la fonction aplatit du TD7

(7)

(define (elimine_doublon_gene liste)

(if (or (null? liste)(null? (cdr liste)) (null? (car liste)))

; il faut notamment envisager que les sous listes soient vides (après élimination des doublons !)

liste

(if (list? (car liste))

(let ((tete_traitee (elimine_doublon_gene (car liste)))) ; ici il y a intérêt à définir localement la variable dont la valeur est le traitement sur la tête

; cela évite d'avoir à recalculer plusieurs fois -dans la fonction suivante on appelle deux fois tete_traitee-

(cons tete_traitee

(elimine_doublon_gene (enleve_gene_aux (flatten tete_traitee) (cdr liste)))))

(cons (car liste)

(elimine_doublon_gene (enleve_gene (car liste) (cdr liste)))))))

; on remarquera que la fonction précédente est récursive non terminale

; avec des fonctions enveloppantes et des traitements de l'appel récursif différents

; le passage à une version itérative est donc très compliqué

;... Qui aura le courage de la chercher ? (Récompense : 20 ! au second trimestre)

;pour les tests (elimine_doublon_gene lis3);(elimine_doublon_gene lis4)

;REMPLACE_LISTE

(define (remplace_lis liste_nb_a_rem liste_nb liste)

; l'idee est que les deux listes liste_nb_a_rem et liste_nb aient la même longueur et soient plates

; on traite le cas où les deux n'ont pas la même longueur par un message d'erreur

; mais pour éviter de faire le test à chaque appel récursif on utilise encore une fonction auxiliaire qui... bosse

; pour vérifier que les listes sont plates il faudrait ajouter un autre test évident

(define (bosse liste_nb_a_rem liste_nb liste) ; fonction facile.... récursive terminale !

(if (null? liste_nb_a_rem) liste

(bosse (cdr liste_nb_a_rem) (cdr liste_nb) (remplace (car liste_nb_a_rem) (car liste_nb) liste))))

(if (= (length liste_nb_a_rem) (length liste_nb)) (bosse liste_nb_a_rem liste_nb liste)

(error " les deux listes n'ont pas la même longueur : "

liste_nb_a_rem (string-append " longueur : " (number-

>string (length liste_nb_a_rem)))

liste_nb (string-append " longueur : " (number->string (length liste_nb)))

)))

(8)

; (remplace_lis '( 1 2 3 4 5) '(101 102 103 104 105) lis2) ;(remplace_lis '( 1 2 3 4 5) '(101 102 103 104 ) lis2) (define (remplace_lis_gene liste_nb_a_rem liste_nb liste) ; mêmes remarques sur les listes à échanger

(define (bosse liste_nb_a_rem liste_nb liste) ; fonction facile.... récursive terminale !

(if (null? liste_nb_a_rem) liste

(bosse (cdr liste_nb_a_rem) (cdr liste_nb) (remplace_gene (car liste_nb_a_rem) (car liste_nb) liste))))

(if (= (length liste_nb_a_rem) (length liste_nb)) (bosse liste_nb_a_rem liste_nb liste)

(error " les deux listes n'ont pas la même longueur : "

liste_nb_a_rem (string-append " longueur : " (number-

>string (length liste_nb_a_rem)))

liste_nb (string-append " longueur : " (number->string (length liste_nb)))

)))

; (remplace_lis_gene '( 1 2 3 4 5) '(101 102 103 104 105) lis3) ;(remplace_lis_gene '( 1 2 3 4 5) '(101 102 103 104 ) lis3)

;Filtre

(define (enleve test? liste) (define (bosse liste)

(if (null? liste) ()

(if (test? (car liste))

(cons (car liste) (bosse (cdr liste))) ; la recursion sur la queue n'est pas faite deux fois donc inutile d'utiliser un let

(bosse (cdr liste))))) (bosse liste))

;(enleve 3 lis2)

(define (enleve_gene test? liste) (define (bosse liste)

(if (null? liste) ()

(if (list? (car liste))

(cons (bosse (car liste)) (bosse (cdr liste))) (if (test? (car liste))

(cons (car liste) (bosse (cdr liste))) (bosse (cdr liste)))))) (bosse liste))

(9)

(define lis_integer (cree_liste_integer 100)) ; creation d'une liste de 100 entiers

(display "lis_integer : ") (display lis_integer)

(newline)

;(enleve_gene odd? lis_integer)

(define lis_integer2 (cons (cons lis_integer (reverse lis_integer)) (cons(reverse lis_integer)

(cons lis_integer '())))) ; creation d'une liste non plate de 100 entiers

(display "lis_intege2r : ") (display lis_integer2)

(newline)

;(enleve_gene odd? lis_integer2)

; on peut s'amuser par exemple à générer la liste des nombres premiers

; qui s'amuse à écrire le prédicat premier?

; ....qui permet de savoir si un nombre est premier (uniquement divisible par 1 et lui-même)

Références

Documents relatifs

En d´ eduire une primitive de ϕ sur un intervalle ne conte- nant pas les valeurs 0 et

Pour tout entier n non nul, on notera V n le fait d’obtenir une boule verte lors du n i´ eme tirage, v n sa probabilité et V n le fait de l’effectuer dans l’urne verte4. De même

Après une mise initiale de 2 euros du joueur, une fonction aléatoire place au hasard successivement trois jetons ( ⋆ ) dans trois cases différentes2. La partie est gagnée si les

Après une mise initiale de 2 euros du joueur, une fonction aléatoire place au hasard successivement trois jetons ( ⋆ ) dans trois cases différentes.. La partie est gagnée si les

Les droites ( F B ) et ( D B ) ont donc la même di- rection et sont alors parallèles ; comme elles ont un point commun, elles sont confondues donc les points D, F et B sont

[r]

(vérifier les réponses avec le tableau fourni plus

Un sac contient des jetons carrés ou ronds, de couleur verte, bleue ou noire.. Il y a 10 jetons verts dont 4 carrés ; 10 des 12 jetons bleus sont carrés ; 14 des 18 jetons noirs