T: / Corrigés des challenges / Python
Manipulation de coordonnées hexadécimales en Python, avec découpage en fonctions et typage pour un code clair et fiable.
On poursuit les corrigés de l’édition 2025 de la Battle Dev Thales. Dans ce challenge, il était question de cryptage de données de coordonnées. Il n’y avait pas de précision particulière quant au système de cryptage mis en oeuvre. Mais en observant les valeurs, on remarquait la présence, en plus des chiffres, des caractères « a » à « f ». Ce qui pouvait laisser penser qu’on était face à un cryptage hexadecimal. C’est donc sur cette base qu’il fallait décrypter, manipuler puis réencoder les coordonnées des escouades.
La difficulté principale du challenge résidait donc plutôt dans la manipulation de ces coordonnées par rapport aux points clés de la carte. Il fallait bien comprendre la mécanique à mettre en œuvre, quitte à faire différents essais jusqu’à trouver la bonne solution.
On va volontairement résoudre ce challenge en découpant le code en plusieurs fonctions :
Puis le programme principal qui orchestre tout ça et crée la réponse attendue.
On s’attardera également sur le typage en Python, en créant un type sur mesure, et en typant correctement toutes les déclarations des fonctions.
Comme on va manipuler souvent un « point » de la carte, on va créer un type dédié, qui correspond à un tableau contenant les coordonnées x et y :
# A mettre au début du code
from typing import List, Tuple
# Type sur mesure
Point = Tuple[int, int]
Les coordonnées de chaque escouade sont sous la forme hexadécimale, par exemple « 345_26d ». Chaque partie correspond à un axe (X et Y), séparés par un _. Pour les rendre exploitables, on doit les convertir en décimal :
def decrypt(coord: str) -> Point:
x_hex, y_hex = coord.split('_')
return (int(x_hex, 16), int(y_hex, 16))
Un peu d’explications :
345 devient alors 837 et 26d devient 621.
Chaque zone sensible (z1, z2, z3) est identifiée est donnée sous la forme x,y. On crée une fonction pour extraire proprement les valeurs x et y :
def parse_zone(zone_str: str) -> Point:
x, y = map(int, zone_str.split(','))
return (x, y)
Un peu d’explications :
Ensuite, il s’agissait de trouver, pour une escouade donnée, la zone sensible la plus proche. Pour cela, il fallait calculer la distance euclidienne (exactement, comme dans le challenge précédent !). Python propose aussi une méthode native pour réaliser cette opération :
# A mettre au début du code
import math
def closest_zone(escouade: Point, zones: List[Point]) -> Point:
x, y = escouade
distances = [math.dist((x, y), (zx, zy)) for zx, zy in zones]
return zones[distances.index(min(distances))]
Un peu d’explications :
Il reste ensuite à créer la fonction qui permet de repousser l’escouade :
def repel(escouade: Point, zone: Point) -> Point:
x, y = escouade
zx, zy = zone
dx = 100 if x >= zx else -100
dy = 100 if y >= zy else -100
return (x + dx, y + dy)
Un peu d’explications :
def encrypt(point: Point) -> str:
return f"{point[0]:x}_{point[1]:x}"
Un peu d’explications :
:x indique qu’on veut afficher le nombre en base 16 (hexadécimal),Et voici le programme principal qui orchestre l’utilisation de toutes ces fonctions créées :
# On parse les zones sensibles
zones = [parse_zone(z) for z in [z1, z2, z3]]
# Traitement des données et utilisation des fonctions
results = []
for coord in coordinates:
decrypted = decrypt(coord)
nearest_zone = closest_zone(decrypted, zones)
repelled = repel(decrypted, nearest_zone)
encrypted = encrypt(repelled)
results.append(encrypted)
# Affichage final
print('-'.join(results))
Pour chaque coordonnées :
Ce challenge nous a permis d’explorer plusieurs facettes essentielles du développement Python.
D’abord, la manipulation du système hexadécimal, à travers la conversion des coordonnées avec int(…, 16) et le formatage inverse via les f-strings (:x). Une belle occasion de comprendre comment Python gère naturellement les bases numériques.
Ensuite, on a structuré la logique en plusieurs fonctions indépendantes, chacune ayant un rôle clair. Cette décomposition rend le code plus lisible, testable et réutilisable : une bonne pratique qu’on retrouve dans tout projet bien conçu.
Enfin, on a introduit le typage des fonctions avec typing, qui documente le code tout en facilitant la détection d’erreurs et la complétion dans les IDE. Un excellent rappel que la clarté du code passe autant par la logique que par la précision de ses signatures !
Other content to discover