Sujet - Verimag

Transcription

Sujet - Verimag
INF121 : Contrôle continu (2h00)
Mars 2012
Documents autorisés : Uniquement une feuille A4 recto-verso de notes personnelles manuscrites.
Notes : Vous répondrez aux exercices et au problème dans l’ordre qui vous convient. Le total des
points de chaque question correspond au nombres de minutes nécessaires pour résoudre la question. Les
questions difficiles sont marquées par des étoiles (**). Vous pouvez admettre le résultat d’une question,
et l’utiliser dans la suite.
Rappel : Définir une fonction signifie :
– Spécification :
1. Profil
2. Sémantique
3. Exemples
– Réalisation :
1. Si elle est récursive :
– Équations récursives
– Terminaison
2. Code OCaml
Exercice 1 : Typage et valeur d’une expression (15 points)
Rappel : fst (a,b) = a et snd (a,b) = b
Pour chaque phrase OCaml, indiquez le type du résultat et sa valeur. Si une expression est mal typée,
indiquez le et justifiez. On donnera également le type des fonctions f et g.
1. (3 points) snd (2,true) && false
2. (3 points) let a = (1,2) in fst (a,2)
3. (3 points) fst (3,2 mod 2 = 0) + 1
4. (3 points) let f (x : int) : int = (x mod 10, x / 10)
in f (snd (f 123))
5. (3 points) let g (x : float) : float ∗ float = (x,x)
in g (g 2.)
Exercice 2 : Fonctions récursives (35 points)
1. (10 points) Définir une fonction récursive qui prend deux entiers a et b et calcule la somme de tous
les entiers entre a et b, a et b compris, ainsi la somme entre a et a vaut a. Nous supposons que
a ≤ b.
2. (6 points) (*) Donner la réalisation d’une autre solution qui effectuera la récursion sur l’autre
argument.
3. (7 points) Écrire une fonction non récursive qui effectue le même calcul, en utilisant uniquement
des additions, soustractions, multiplications et divisions. Nous supposons que a ≤ b.
4. Complexité :
– (2 points) Donner le nombre total d’appels récursifs faits dans la fonction écrite à la question 1.
– (2 points) Compter le nombre d’opérations effectuées dans la fonction écrite à la question 3.
– (4 points) Considérons que les additions, soustractions, multiplications et divisions coûtent le
même temps. Quel est l’algorithme qui est le plus rapide ?
– (4 points) Considérons que chaque addition, soustraction prend t fois moins de temps que chaque
multiplication ou division. Déterminer la valeur de t pour que l’algorithme 1 utilise moins d’opérations que celui de la fonction demandée à la question 3.
1
Exercise 3 : Jouons au Tarot (75 points)
Un jeu de tarot comporte 78 cartes à jouer :
– Cinquante-six cartes réparties en quatorze cartes des quatre couleurs traditionnelles : pique, cœur,
carreau et trèfle. La différence avec un jeu traditionnel de 52 cartes est le cavalier, figure s’intercalant
entre la dame et le valet. Dans l’ordre décroissant de force et de valeur, on trouve donc :
+ les honneurs : Roi, Dame, Cavalier et Valet
+ les petites : 10, 9, 8, 7, 6, 5, 4, 3, 2, 1. Le 1 est la plus petite carte du paquet contrairement à
ce qui se pratique dans de nombreux jeux où l’As est plus fort que le Roi.
– Vingt et une cartes portant un numéro : ce sont les atouts (ou tarots) qui ont priorité sur les
couleurs. Le numéro indique la force de chaque atout, du plus fort, le 21, au plus faible, le 1.
– L’« excuse », une carte marquée d’une étoile et représentant un joueur de mandoline. Il s’agit d’une
sorte de joker.
a) Modélisation (7 points)
Nous définissons les types suivants :
type dos = | Petite of int
| Valet
| Cavalier
| Dame
| Roi;;
type couleur = Trefle | Pique | Carreau | Coeur ;;
type carte = | Atout of int
| Excuse
| Normale of dos ∗ couleur ;;
type carteliste = Nil
| Cons of carte ∗ carteliste;;
Nous définissons le type main qui modélise l’ensemble des cartes en possession d’un joueur, par type
main = carteliste. Nous définissons le type pli qui représente l’ensemble des cartes gagnées à chaque
tour de jeu par type pli = carteliste.
Notre modélisation doit être valable pour 3, 4 ou 5 joueurs.
1. (7 points) Représentez en OCaml (dans votre type) la main contenant les cartes suivantes : « valet
de pique », « 9 d’atout », « excuse », « roi de carreau », « 9 de coeur », « 21 d’atout ».
b) Points (40 points)
À la fin de la partie, on compte les points contenus dans les plis (i.e., les cartes prises par un groupe
de joueur). On omet de nombreuses règles subtiles du tarot ici, pour se concentrer sur l’essentiel. Chaque
carte vaut un nombre précis de point, donné par la règle suivante :
– Atout 1, Excuse et Atout 21 : 4.5 points
– Roi : 4.5 points
– Dame : 3.5 points
– Cavalier : 2.5 points
– Valet : 1.5 points
– Toute autre carte : 0.5 points
1. (2 points) Combien de points compte la main donnée à la question a)1) ?
2. (2 points) Combien de points compte le pli qui est composé des cartes “valet de pique”, “douze
d’atout ”, “excuse” et “roi de carreau” ?
3. (6 points) Définir une fonction valeur: carte → float, qui à une carte associe son nombre de
points.
4. (7 points) Définir la fonction compte: pli → float, qui compte les points contenus dans un pli.
2
5. (10 points) Nous considérons le type suivant :
type pliliste = Nil
| Cons of pli ∗ pliliste;;
Définir une fonction veriftotal: pliliste → bool, qui vérifie que le total des points de la liste
des plis passés en paramètre est bien 91 points. Vous pouvez réutiliser la fonction compte de la
question précédente et toute autre fonction intermédiaire que vous jugerez nécessaire.
6. (6 points) Définir une fonction nbatout: main → int, qui compte le nombre d’atouts contenus dans
une main passée en paramètre.
7. (7 points) Si un joueur possède plus de 10 atouts dans sa main intiale, il peut obtenir des points
bonus, nous dirons qu’il a une poignée. Plus précisément une simple poignée correspond à au moins
10 Atouts et au plus 12 Atouts et une prime de 20 points, une double poignée correspond à au
moins 13 Atouts et au plus 14 et une prime de 30 points et une triple poignée correspond à au
moins 15 Atouts et à une prime de 40 points. Définir la fonction pointbonus: main → float, qui
détermine en fonction de la main d’un joueur le nombre de points bonus attribués en fonction de
son nombre d’atouts. Vous devrez réutiliser la fonction nbatout de la question précédente.
c) Vérification (28 points)
Afin de détecter les éventuels tricheurs nous allons vérifier que les cartes ne sont jouées qu’une seule
fois.
1. (8 points) Définir une fonction appart : carte → pli → bool qui détermine si une carte donnée
appartient à un pli.
2. (8 points) Définir une fonction oter : carte → main →
d’une carte donnée dans une main.
main qui supprime toute les occurrences
3. (12 points) Définir une fonction unicite : main → bool qui détermine si une main ne contient pas
deux fois la même carte. Vous pouvez utiliser la fonction appart.
d) Jeu de la carte (***) BONUS (20 points)
Définir une fonction qui détermine étant donné un pli d’au moins une carte, la carte qui l’emporte.
Vous pouvez d’abord définir des fonctions intermédiaires avant de répondre à cette question.
Nous indiquons les règles élémentaires du tarot permettant de déterminer qui emporte un pli.
– Si la première carte est un atout, c’est l’atout le plus fort présent dans le pli qui l’emporte.
– Si la première carte détermine la couleur jouée, alors c’est l’atout le plus fort présent dans le pli qui
l’emporte, sinon s’il n’y a pas d’atout, c’est la plus forte carte de la couleur jouée qui l’emporte.
– Si la première carte d’un pli est l’excuse, c’est la carte suivante qui détermine la couleur jouée.
Rappel Soit un type défini par type alphabet = A | B | C;; alors A>B>C.
3

Documents pareils