Corrigé

Transcription

Corrigé
Introduction à la Programmation 1
Contrôle continu 2
Corrigé
Université Paris-Diderot
26 novembre 2015
Exercice 1
(1 point)
Réécrivez les fragments de code ci-dessous en corrigeant les erreurs afin d’avoir
des programmes que le compilateur peut compiler.
class Main ( String args []) {
for ( i =0 , i <10 , i +=2) {
boolean b = ( i =0) ;
if b {
System . out . print ( i ) ;
}
}
}
}
class Main {
public static void main ( String [] args ) {
for ( int i =0; i <10; i +=2) {
boolean b = ( i ==0) ;
if ( b ) {
System . out . print ( i ) ;
}
}
}
}
public static String 10 concat ( String [] x ) {
String s = " " ;
int n = 0;
int len = intArrayLength ( x ) ;
while (i < len && n <10) {
s = s + x [ i ];
n = n + stringLength ( x [ i ]) ;
i = i +1;
}
1
return n ;
}
public static String concat10 ( String [] x ) {
String s = " " ;
int n = 0;
int i = 0;
int len = stringA rrayLeng th ( x ) ;
while (i < len && n <10) {
s = s + x [ i ];
n = n + stringLength ( x [ i ]) ;
i = i +1;
}
return s ;
}
Exercice 2
(2 points)
On rappelle qu’un tableau t est image miroir d’un autre tableau u si on obtient
t en lisant u de droite à gauche. Par exemple, t = {1, 2, 3} et u = {3, 2, 1} sont
image miroir l’un de l’autre, mais pas t0 = {1, 2, 3} et u0 = {3, 3, 1, 1}. On considère
le code ci-dessous.
// renvoie vrai si t est l’image miroir de u, faux sinon
public static boolean are_mirror ( int [] t , int [] u ) {
int len = intArrayLength ( t ) ;
for ( int i =0; i < len ; i ++) {
if ( t [ i ]!= u [ len - i ]) {
return false ;
}
}
return true ;
}
1. lesquelles des affirmations suivantes sont vraies ?
le code contient une erreur de syntaxe
le code contient une erreur de typage
la fonction peut produire une erreur à l’exécution
la fonction peut ne pas produire d’erreur et respecter sa spécification
la fonction peut ne pas produire d’erreur mais ne pas respecter sa spécification
2. Corrigez le code.
public static boolean are_mirror ( int [] t , int [] u ) {
int len = intArrayLength ( t ) ;
if ( len != intArrayLength ( u ) ) {
return false ;
2
}
for ( int i =0; i < len ; i ++) {
if ( t [ i ]!= u [ len -i -1]) {
return false ;
}
}
return true ;
}
Exercice 3
(2 points)
Écrivez une fonction int floor_log(int n) qui prend en paramètre un entier
n relatif et renvoie le nombre de fois où il faut diviser n par deux pour arriver à 1,
autrement dit blog2 (n)c. La fonction renverra l’entier −1 si le logarithme n’est pas
défini.
Contrat:
floor_log(15) renvoie 3,floor_log(16) renvoie 4,floor_log(-3) renvoie -1.
public static int floor_log ( int x ) {
if (x <1) return -1;
int res = 0;
while ( x !=1) {
x = x / 2;
res = res + 1;
}
return res ;
}
Exercice 4
(2 points)
Écrivez une fonction qui prend en paramètre un tableau de tableaux d’entiers
t et renvoie une chaîne de caractères le représentant dans la syntaxe Java. Par
exemple, si t vaut {{1,2},{},{3}}, la fonction renverra la chaîne de caractères
"{{1,2},{},{3}}".
public static String intAr ray2ToSt ring ( int [][] t ) {
int len = i n tA r r ay A rr a yL e n gt h ( t ) ;
String res = " { " ;
for ( int i =0; i < len ; i ++) {
res = res + " { " ;
int len2 = intArrayLength ( t [ i ]) ;
for ( int j =0; j < len2 ; j ++) {
res = res + t [ i ][ j ];
if ( j != len2 -1) { res = res + " ," ;}
}
res = res + " } " ;
if ( i != len -1) {
res = res + " ," ;
}
3
}
res = res + " } " ;
return res ;
}
Exercice 5
(4 points)
On représente les entiers naturels (pas les entiers machine) par des tableaux
contenant leur représentation décimale. Par exemple, l’entier 21340930923 est représenté par le tableau {2, 1, 3, 4, 0, 9, 3, 0, 9, 2, 3}.
Écrivez une fonction qui prend en paramètre deux tableaux représentant deux
entiers naturels, et renvoie un tableau représentant la somme de ces deux entiers naturels. Par exemple, si les deux tableaux passés en argument sont {1, 9} et {2, 3, 1},
la fonction pourra renvoyer {2, 5, 0}. Elle pourra aussi, si c’est plus simple à programmer, renvoyer {0, 2, 5, 0}.
Remarque : il n’est pas possible de convertir un entier naturel en entier machine,
on ne peut donc pas utiliser la somme des entiers machines (en dehors des entiers
machines compris entre 0 et 9) pour faire la somme de deux entiers naturels.
public static int ith_decimal ( int [] x , int i ) {
int len = intArrayLength ( x ) ;
if (i >= len ) {
return 0;
} else {
return x [ len -i -1];
}
}
public static int [] sum ( int [] x , int [] y ) {
int lenx = intArrayLength ( x ) ;
int leny = intArrayLength ( y ) ;
int len ;
if ( lenx > leny ) {
len = lenx ;
} else {
len = leny ;
}
int [] res = new int [ len +1];
int car = 0;
for ( int i =0; i < len ; i ++) {
int s = ith_decimal (x , i ) + ith_decimal (y , i ) + car ;
res [ len - i ] = s % 10;
car = s /10;
}
res [0] = car ;
return res ;
}
4
Exercice 6
(5 points)
On représente la courbe de niveau d’une étape du tour de France par un tableau.
Par exemple, le tableau t = {112, 114, 111, 120, . . .} représente une étape telle que
l’altitude moyenne sur le premier kilomètre est de 112m, puis de 114m sur le second
kilomètre, etc.
Chaque kilomètre pédalé consomme 1000 unités caloriques, et chaque côte de
dénivellé d (en mètre) de 1 kilomètre de long consomme d unités caloriques supplémentaires. On suppose que le cycliste ne pédale pas en descente.
Écrivez une fonction int distance_parcourue(int []t,int n), qui prend
en argument un tableau t représentant une courbe de niveau et un entier n, et
qui renvoie le nombre maximal de kilomètres parcourus en disposant de n unités
caloriques au départ.
Contrat:
Avec t comme ci-dessus,
— distance_parcourue(t,n) renvoie 0 si n < 1002 (on ne finit pas le premier
kilomètre),
— distance_parcourue(t,1002) renvoie 2 (on finit le premier kilomètre, et on
se laisse descendre sur le second).
public static int d is ta nce _p ar cou ru e ( int [] t , int n ) {
int len = intArrayLength ( t ) ;
if ( len ==0) return 0;
int alt = t [0];
int i = 0;
while (i < len -1 && n >=0) {
if ( alt <= t [ i +1]) {
n = n - 1000 - ( t [ i +1] - alt ) ;
}
alt = t [ i +1];
if (n >=0) i ++;
}
if (n >=1000) {
return len ;
} else {
return i ;
}
}
Exercice 7
(2 points)
Un tableau t de taille n est une permutation si t contient tous les entiers entre
0 et n − 1. Par exemple, le tableau {2,3,0,1} est une permutation, mais ni
{1,2,1,0}, ni {1,2} ne sont des permutations. Le tableau u représente la permutation inverse de t si la case u[i] contient l’indice de la case de t qui contient i,
autrement si t[u[i]] = i. Par exemple, la permutation inverse de {2,3,4,0,1} est
{3,4,0,1,2}.
Écrivez une fonction qui prend en argument un tableau t représentant une permutation et renvoie un tableau u qui représente la permutation inverse de t. On
cherchera le code le plus court et le plus efficace possible.
5
public static int [] inverse ( int [] t ) {
int len = intArrayLength ( t ) ;
int [] res = new int [ len ];
for ( int i =0; i < len ; i ++) {
res [ t [ i ]] = i ;
}
return res ;
}
Exercice 8
(6 points)
Le chef de train de l’Orient Express doit aménager le wagon restaurant avant le
départ du train. Ce wagon est assez petit et doit être le moins possible encombré
de tables. Le chef de train consulte son cahier de réservations pour déterminer le
nombre minimal de tables à installer. Son cahier contient les groupes ayant réservé
et une estimation du temps qu’ils passeront à table.
0.
1.
2.
3.
4.
Le marquis de Quaramba de 19h00 à 19h59
La Vociafiore de 19h15 à 20h29
Le baron et la baronne von Münchhausen de 19h30 à 20h14
Le colonel Poivronet de 20h00 à 20h59
Le professeur Cook de 20h30 à 21h59
Le chef de train vous appelle pour l’aider à résoudre son problème, et après avoir
dessiné un “diagramme espace-temps”
2
4
1
0
3
vous lui dites qu’il doit préparer 3 tables. Pour éviter qu’il vous rappelle le jour
suivant, vous décidez de lui envoyer aussi une fonction qui résoud le problème de
façon générale.
Vous représentez le contenu du cahier de réservation par un tableau de couples
d’entiers. Par exemple, le cahier de réservation ci-dessus pourra être représenté par
int [][] cahier =
{{1900 ,1959} ,{1915 ,2029} ,{1930 ,2014} ,
{2000 ,2059} ,{2030 ,2159}};
Vous représentez par ailleurs le diagramme espace-temps par un tableau de couples
d’entiers contenant les extrémités de segments listées dans l’ordre temporel, et
identifiées par leur numéro de segment. Par exemple, le diagramme ci-dessus sera
représenté par le tableau de couples d’entiers
int [][] diagramme =
6
{{1900 ,0} ,{1915 ,1} ,{1930 ,2} ,{1959 ,0} ,{2000 ,3} ,
{2014 ,2} ,{2029 ,1} ,{2030 ,4} ,{2059 ,3} ,{2159 ,4}};
1. On admet à cette question que vous avez une fonction
int [][]calcule_diagramme(int [][]cahier) qui renvoie le diagramme
associé à un cahier. En déduire une fonction int nb_tables(int [][]
cahier) qui calcule le nombre minimal de tables à installer.
2. Écrivez la fonction int [][]calcule_diagramme(int [][]cahier).
Indication : on pourra, par exemple, utiliser et coder une fonction
void tri2(int [][]t) qui trie un tableau t de couples en fonction du premier élément du couple, de sorte que si le tableau t vaut {{3, −1}, {1, 23}, {4, 2}},
alors après avoir effectué tri2(t), il vaut {{1, 23}, {3, −1}, {4, 2}}.
public static int nb_tables ( int [][] cahier ) {
int [][] diagramme = cal cule_dia gramme ( cahier ) ;
int nb_resa = i n tA r ra y Ar r a yL e ng t h ( cahier ) ;
boolean [] deja_vu = new boolean [ nb_resa ];
// on initialise le tableau deja_vu a faux
// (inutile en Java)
for ( int i =0; i < nb_resa ; i ++) {
deja_vu [ i ] = false ;
}
int res = 0;
int n = 0;
for ( int i =0; i <2* nb_resa ; i ++) {
int seg = diagramme [ i ][1];
if ( deja_vu [ seg ]) {
// c’est une fin de repas
n = n -1;
} else {
// c’est un debut de repas
n = n +1;
deja_vu [ seg ]= true ;
if (n > res ) {
res = n ;
}
}
}
return res ;
}
public static void insere_couple ( int [][] t , int i ) {
int len = i n tA r r ay A rr a yL e n gt h ( t ) ;
for ( int j = 0; j < i ; j ++) {
if ( t [ i ][0] < t [ j ][0]) {
int [] c = t [ j ];
t [ j ]= t [ i ];
t[i] = c;
}
}
7
}
// trie les couples de t
// par ordre croissant de premiere composante
public static void tri2 ( int [][] t ) {
int len = i n tA r r ay A rr a yL e n gt h ( t ) ;
for ( int i =1; i < len ; i ++) {
insere_couple (t , i ) ;
}
}
public static int [][] calcu le_diagr amme ( int [][] cahier
){
int len = i n tA r r ay A rr a yL e n gt h ( cahier ) ;
int [][] res = new int [2* len ][2];
for ( int i =0; i < len ; i ++) {
res [2* i ][0] = cahier [ i ][0];
res [2* i +1][0] = cahier [ i ][1];
res [2* i ][1] = res [2* i +1][1] = i ;
}
tri2 ( res ) ;
return res ;
}
// FIN
8