Corrigé CCINP 2026 Sciences industrielles MP — Partie V (Q37 à Q46) : Optimisation du parcours de marquage (ITC) : dictionnaire, plus proche extrémité, glouton
Sujet officiel du concours CCINP, session 2026, épreuve Sciences industrielles MP. Corrigé rédigé par Ibrahim Alame.
Sujet officiel (PDF, site du concours)
Énoncé
Exigence 1.2.3 : minimiser les distances parcourues lors d'un tracé. Les lignes à tracer sont extraites d'un fichier texte dont la première ligne est un en-tête et dont chaque ligne suivante donne les coordonnées (en m) des deux extrémités d'un trait, séparées par des tabulations. On les range dans un dictionnaire traces : clé entière = numéro du trait dans l'ordre de lecture du fichier (à partir de ) ; valeur = liste de deux 2-uplets de flottants . Exemple : carré de divisé en quatre (fichier carre.txt, Figure 17), dont le dictionnaire commence par \{0: [(0.0, 0.0), (1.0, 0.0)], 1: [(0.0, 0.0), (0.0, 1.0)], ...\}.
xp1 | yp1 | xp2 | yp2 |
|---|---|---|---|
0. | 0. | 1. | 0. |
0. | 0. | 0. | 1. |
1. | 1. | 0. | 1. |
1. | 1. | 1. | 0. |
0.5 | 0. | 0.5 | 1. |
0. | 0.5 | 1. | 0.5 |
{ Figure 17 — Fichier carre.txt (à gauche) et tracé obtenu (à droite).}
Script du DR (Q38), création du dictionnaire (les ... sont à compléter) :
nom_fichier = "rugby.txt"
traces = {}
fichier = open(nom_fichier, "r"):
k = 0
for line in fichier:
if k == 0:
k += 1
else:
ligne = line.split()
...
...
traces[...] = [P1, P2]
k += 1
fichier.close()
Fonction PPE (plus proche extrémité) donnée au DR (Q41), et squelette de trajet (Q42) :
def PPE(init, voisin):
dmin = float("inf")
for k in voisin:
for j in range(2):
dist_voisin = distance(init, voisin[k][j])
if dist_voisin < dmin:
dmin = dist_voisin
(t, p) = (k, j)
return (t, p)
def trajet(init, traits):
parcours = []
pos_init = init
for k in range(len(traits)):
...
...
...
del traits[...]
return parcours
Une ligne se trace d'un seul tenant, dans un sens quelconque ; on minimise, après chaque trait, la distance euclidienne jusqu'au début du trait suivant. trajet(init, traits) renvoie la liste des couples (clé du trait, indice de l'extrémité de départ). Pour Q45, le DR compare le test dist_voisin < dmin (cas a) et dist_voisin <= dmin (cas b).
Q37. Rôle de la variable k et de la structure conditionnelle sur sa valeur.
Q38. Les deux lignes manquantes et la clé du dictionnaire.
Q39. Écrire distance(A, B) (distance euclidienne) avec sqrt du module math.
Q40. Signature et spécification de PPE.
Q41. Commenter chaque ligne de PPE.
Q42. Compléter trajet.
Q43. Après trajet((0,0), traces), peut-on encore utiliser traces ?
Q44. traces1 = copy(traces) placé juste après fichier.close() résout-il le problème ?
Q45. Conséquence des cas a et b sur le choix de l'extrémité la plus proche.
Q46. Dessiner, pour trajet((0,0), traces) sur carre.txt et dans les deux cas, l'ordre de tracé (numéro), le sens (flèche) et les trajets sans peinture (pointillés numérotés et fléchés).
Corrigé
Q37. k compte les lignes du fichier déjà lues. La première ligne (k == 0) est l'en-tête xp1 yp1 xp2 yp2 : elle ne contient pas de nombres (float("xp1") lèverait une erreur) et ne décrit aucun trait ; on se contente donc d'incrémenter k pour la sauter. Pour les lignes suivantes, k vaut pour le premier trait, pour le deuxième, etc. : il sert à numéroter les traits dans l'ordre de lecture, donc à construire la clé.
Q38. line.split() découpe la ligne aux blancs (espaces et tabulations) en une liste de quatre chaînes, qu'on convertit en flottants :
P1 = (float(ligne[0]), float(ligne[1]))
P2 = (float(ligne[2]), float(ligne[3]))
traces[k - 1] = [P1, P2]
La clé est k - 1 : le premier trait (lu quand k vaut ) reçoit la clé , comme dans l'exemple \{0: [(0.0, 0.0), (1.0, 0.0)], ...\}. On notera que la ligne fichier = open(nom_fichier, "r"): du DR porte un deux-points parasite (il faudrait fichier = open(nom_fichier, "r") sans « : », ou with open(nom_fichier, "r") as fichier:) ; la correction attendue ne porte pas sur ce point.
Q39.
from math import sqrt
def distance(A: (float, float), B: (float, float)) -> float:
"""
Renvoie la distance euclidienne entre les deux points A et B
"""
return sqrt((B[0] - A[0])**2 + (B[1] - A[1])**2)
(Avec import math, on écrirait math.sqrt(...).)
Q40.
def PPE(init: (float, float), voisin: dict) -> (int, int):
"""
init : position courante (x, y) du robot.
voisin : dictionnaire NON VIDE {clé : [(x1, y1), (x2, y2)]}
des traits restant à tracer.
Renvoie (t, p) : t clé du trait, p (0 ou 1) indice de
l'extrémité de ce trait la plus proche de init
(distance euclidienne).
"""
Précondition : voisin non vide (sinon (t, p) n'est jamais affecté et le return lève une erreur).
100 % gratuit
La suite du corrigé est sur Adloun
Le corrigé rédigé en entier, question par question, et le tuteur pour poser des questions sur ce sujet.
Voir le corrigé complet, gratuitementInscription gratuite en 30 secondes (e-mail, nom d'utilisateur, mot de passe, classe ou profil), sans carte bancaire : arrivée directe sur le corrigé.