TABLE DES MATIERES
Le problème codingame Detective Pikaptcha est un problème de labyrinthe, inspiré de l'univers de pokemon. Comme son nom l'indique, il fait réference au célèbre pokemon Pikachu. Le but du premier épisode de ce problème est de faire l'analyse d'un labyrinthe. Le principe est de retourner un labyrinthe similaire à celui que l'on nous fourni, mais en modifiant certaines cases et en inscrivant sur ces dernières le nombre de passages qui leurs sont adjacent. On considère qu'un passage peut avoir un maximum de 4 cases adjacentes (on ne considère pas les cases en diagonales commes adjacentes). Pour résoudre ce problème, le site codingame nous fourni un certain nombre d'entrée.
La stratégie avec laquelle j'ai abordé ce problème se décompose en plusieurs parties. Tout d'abord, j'ai récupéré les entrées données par le site Codingame, j'ai donc voulu stocker le labyrinthe dans un tableau à 2 dimentions afin de pouvoir le manipuler de façon simple par la suite. J'ai également récupéré les valeurs de hauteur et longueur du labyrinthe.
Une fois cela fais, je me suis occupé de la boucle principale du programme. Elle consiste en parcourir toutes les cases du tableau et à vérifier si elles sont adjacentes à d'autres passages. J'ai donc éliminé de cette boucle les cases étant des murs (puisqu'il ne fallait pas changer leur valeur). Ensuite j'ai regardé de chaque coté de chaque cases pour vérifier les élements qui les entouraient. A la fin de chaque vérification, j'ai modifié la valeur de départ de la case traité, en fonction des résltats de la boucle.
Enfin, lorsque toutes les cases étaient traitées, il ne me restait plus qu'à afficher le résultat sous la forme d'un tableau en deux dimensions, avec les valeurs modifiées à l'intérieur.
Penchons nous désormais plus en détail sur le code qui m'a permis de résoudre ce problème. J'ai écris ce code en C, en utilisant uniquement la fonction main car il était assez court et ne nécessitait pas de séparation du code en plusieurs parties. J'ai donc commencé par initialiser mes variables, qui sont toutes des entiers, sauf le tableau à deux dimensions qui utilisera le type caractère char. Puis j'ai créé une boucle afin de récupérer les données du labyrinthe. En effet, comme le site Codingame nous fourni le labyrinthe ligne par ligne, il est important de stocker les lignes une à une dans le tableau à deux dimensions.
Par la suite, on crée une double boucle for qui permettra de parcourir toutes les cases du labyrinthe sans en oublier. En effet, si on définit les coordonnées d'une case dans le labyrinthe sous la forme (i,k), alors on parcour grace à cette boucle tout les couples (i,k) possibles. On considère ici que la valeur maximale de i est la hauteur du labyrinthe, et la valeur maximale de k, est la longueur du labyrinthe.
Alors pour chaque case du labyrinthe on va vérifier plusieurs conditons à l'aide de l'instruction if. Tout d'abord on vérifie que la case que l'on traite est un passage. Puis, si c'est un passage, pour ne pas avoir d'erreurs liées aux index des cases que l'on regarde, on va vérifier si la case n'est pas sur un bord. Si tel est le cas, alors on ne regardera pas le coté qui correspond au bord.
Enfin on incrémente de 1 la case que l'on observe, si le test est passé, et ce pour chacun des 4 tests. A la fin du programme on réalise une double boucle for afin d'afficher la solution de la manière attendu. On va parcourir chaque ligne du tableau, et afficher chaque élement un à un. Une fois une ligne affiché, on effectue un retour à la ligne, puis on réitère l'opération pour la ligne suivante.
Si dessous, voici une version en pseudo code de la boucle principale de mon programme, afin de mieux comprendre son fonctionnement.
Pour i allant de 0 à la valeur de la hauteur du labyrinthe Pour k allant de 0 à la valeur de la longueur du labyrinthe Si la case de coordonnées (i,k) est un 0 Si la case (i,k) n'est pas sur le bord gauche Et que la case à sa gauche n'est pas un mur Alors on ajoute 1 à la valeur de (i,k) Si la case (i,k) n'est pas sur le bord droit Et que la case à sa droite n'est pas un mur Alors on ajoute 1 à la valeur de (i,k) Si la case (i,k) n'est pas sur la dernière ligne Et que la case du dessous n'est pas un mur Alors on ajoute 1 à la valeur de (i,k) Si la case (i,k) n'est pas sur la première ligne Et que la case du dessus n'est pas un mur Alors on ajoute 1 à la valeur de (i,k)
Voici ci dessous ma proposition de code commenté pour résoudre le problème Pikaptcha épisode 1.
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <stdbool.h> // Fonction principale int main() { // Initialisation des variables int width; // Longueur du labyrinthe int height; // Hauteur du labyrinthe int i; int k; scanf("%d%d", &width, &height); // Récupération des données correspondantes char table[256][256]; // Création d'un tableau à deux dimentions // Récupération du labyrinthe dans un tableau à deux dimentions for (i = 0; i < height; i++) { char line[256]; scanf("%s", line); for (k = 0; k < width; k++) { table[i][k] = line[k]; } } // Boucle principale for (int i = 0; i < height; i++) { // i l'indice de l'ordonnée dans le tableau de la case traitée dans for (int k = 0; k < width; k++){ // k l'indice de l'abscisse dans le tableau de la case traitée dans if(table[i][k] == '0'){ // test si la case que l'on regarde est un passage if((i != 0)&&(table[i-1][k] != '#')){ // test si la case du dessus est un passage table[i][k] ++; } if((i != height-1)&&(table[i+1][k] != '#')){ // test si la case du dessous est un passage table[i][k] ++; } if((k != 0)&&(table[i][k-1] != '#')){ // test si la case de gauche est un passage table[i][k] ++; } if ((k != width-1)&&(table[i][k+1] != '#')){ // test si la case de droite est un passage table[i][k] ++; } } } } // Affichage de la solution for (i = 0; i < height; i++) { for (k = 0; k < width; k++){ printf("%c", table[i][k]); } printf("\n"); } return 0; }
Afin de valider notre réponse, le site Codingame effectu différents test. Ils peuvent également nous aider à résoudre le problème. Alors voici ci dessous les entrées et sorties de différents test effectués, accompagnés d'une remarque si le test a aidé à la réalisation d'une partie spécifique du programme.
> 0000# > #0#00 > 00#0#
> 1322# > #2#31 > 12#1#
Ce test est le plus important, c'est celui d'origine. Il permet de comprendre la base du problème et, si le problème ne comporte que peu de cas particuliers, il peut permettre de le résoudre dans son intégralité.
> 0#0 > #0# > 0#0
> 0#0 > #0# > 0#0
Ce test permet de coder le mécanisme lié au bord de façon plus précise, et il permet également de constater que l'entrée et la sortie peuvent être la même.
> #00###000 > 000000000 > 000##0000
> #22###232 > 244223443 > 232##2332
Ce test permet de vérifier si le programme fonctionne à plus grande échelle.
Beaucoup d'autres utilisateurs de la plateforme Codingame ont essayé de résoudre le problème Détective Pikaptcha ep1. Parmi eux, l'utilisateur "lhm". J'ai décidé de présenter son code même si il utilise le même principe que moi, car il est beaucoup plus compact. En effet, même si il perd légerement en lisibilité, il a su utiliser la syntaxe du C afin d'optimiser au maximum le nombre de lignes de son code. Je trouve donc cette solution intéressante car elle permet de montrer que, malgré la syntaxe plutot exigente de ce langage, il est possible d'être assez rapide lors de l'écriture de la solution. Son code est donc pratique lorsque l'on fait des test ou lorsque l'on résout des problèmes personnels, mais je le déconseillerais lorsqu'il s'agit de gros projets, ou de travaux de groupe à présenter. En effet, le manque d'aération dans le code et le regroupement d'un certain nombre d'instruction par ligne le rend plus difficile à comprendre. De plus, dans la version originale, le code n'est pas commenté.
Quand au fonctionnement de son programme, il est similaire au mien. L'utilisateur va d'abord récupérer les informations données par le site, la longueur et hauteur du labyrinthe, ainsi que les lignes du labyrinthe. Puis, il va parcourir le labyrinthe à l'aide d'une double boucle, et tester si la case qu'il traite est un passage. Si tel est le cas, les coordonnées de chaque passage passent différents test afin de savoir si la case se situt sur un bord, et si elle est entouré par des passages ou des murs, il modifi alors les cases en fonction des résultats des tests. Ensuite il affiche le labyrinthe modifié ligne par ligne. Il fait cela à l'intérieur de sa double boucle principale, ce qui lui évite de recréer une boucle pour afficher le résultat, et son programme gagne donc en efficacité par rapport à ma proposition.
Voici ci dessous le code commenté de l'utilisateur "lhm".
#include <stdlib.h> #include <stdio.h> #include <string.h> main() { int w, h; scanf("%d%d", &w, &h); // Récupération des dimentions du labyrinthe char line[101][101]; // Creation d'un tableau for (int i = 0; i < h; i++) {scanf("%s", line[i]); } // Récupération des lignes du labyrinthe for (int i = 0; i < h; i++) { // Création d'une double boucle pour parcourir le labyrinthe for (int j = 0; j < w; j++) { if (line[i][j] != '#') { if( i > 0 && line[i-1][j ] != '#' ) { line[i][j]++; } // vérifi si la case du dessus est un passage if( i < h-1 && line[i+1][j ] != '#' ) { line[i][j]++; } // vérifi si la case du dessous est un passage if( j > 0 && line[i ][j-1] != '#' ) { line[i][j]++; } // vérifi si la case de gauche est un passage if( j < w-1 && line[i ][j+1] != '#' ) { line[i][j]++; } // vérifi si la case de droite est un passage } } printf("%s\n", line[i]); // Affichage du résultat } }
Ce travail m'a tout d'abord permis d'approfondir mes connaissances en matière de gestion de coordonnées. En effet, le mécanisme selon lequel il faut regarder uniquement certaines cases, en fonction de si elles se situent ou non sur les bords était très intéressant. De plus j'ai pu apprendre à manipuler un nouvel élement en C, les tableaux. Enfin, la rédaction de ce rapport en langage HTML et CSS m'a permis de réviser les bases de ce langages que j'avais eu l'occasion d'étudier précedement, ainsi que d'approfondir mes connaissances, notamment en ce qui concerne la gestion des espaces et du style CSS.
Le problème codingame Detective Pikaptcha épisode 2 est un problème de labyrinthe. C'est la suite du problème précedent. Mais cette fois ci, la situation va se compliquer. Le but de cet épisode va être de faire longer un mur à Pikachu, jusqu'à ce qu'il revienne à son point de départ. Chaque fois qu'il passera sur une case, il faudra ajouter 1 à cette case. Le but du problème sera donc de renvoyer un labyrinthe modifié, avec sur les cases "passages", le nombre de fois que Pikatchu les a parcouru. Pour cela, le site codingame nous donnes un certain nombre d'éléments en entrée.
Afin de mieux comprendre l'énoncé du problème, voici ci dessous un exemple de chemin que Pikachu doit suivre si on souhaite qu'il longe le labyrinthe par la gauche. Les cases jaunes représentent les murs, est les blanches les passages.
Mon programme se divise en plusieurs parties. Tout d'abord, la récupération des différentes entrées données par Codingame, tel que les dimensions du labyrinthe, le coté que Pikatchu doit longer, ou encore les lignes du labyrinthe. Puis on initialise plusieurs variables qui vont nous aider à résoudre le problème. En effet on aura besoin d'une copie du labyrinthe donné en entrée, afin d'avoir un labyrinthe intact, et l'autre modifiable. Il nous faudra également connaitre le point de départ de Pikachu, afin de connaitre les conditions qui feront s'arréter le programme. Ensuite, après avoir remarqué que Pikachu regardait les cases une à une, selon un cycle, on défini une fonction qui nous permettra de connaitre ce cycle, en fonction du mur que Pikachu doit longer (gauche ou droite). A partir de ce cycle, il nous est possible de créer une fonction qui va permettre à Pikachu de se déplacer selon un ordre précis.
Alors, on peut créer le programme principal, qui utilisera les fonctions créées précedement et qui tournera tant que Pikachu ne sera pas retourné au point de départ. Enfin, lorsque la boucle principale se sera arrété, on retournera le résultat à l'aide d'une boucle qui affichera le tableau obtenu ligne par ligne.
Ce programme use de mécanismes assez particuliers qu'il faut comprendre afin de pouvoir résoudre le problème.
Tout d'abord, le mécanisme du cycle. En effet Pikachu va regarder chaque case qui l'entoure selon un cycle précis qui prendra en compte l'orientation de Pikachu, ainsi que le mur qu'il devra longer. Avant de rentrer plus en détail dans le code du cycle, regardons comment cette mécanique fonctionne à l'aide de deux tableaux excel.
Afin de coder les résultats de ces observations, j'ai utilisé une liste. On retrouve la méthode que je vais détailler dans la fonction cycle de mon programme. Il fallait distinguer plusieurs cas dans cette fonction. Tout d'abord, il fallait distinguer le cas coté gauche et coté droit. Alors en fonction du coté, le programme affecte à la variable direction une liste représentant le cycle à suivre.
Alors, grace aux tableaux excel on peut se rendre compte de la chose suivante. Si l'orientation de Pikachu correspond au premier élement de la liste, lors de son prochain mouvement il regardera d'abord dans toutes les autres directions avant de regarder dans celle qu'il pointe. Et si l'orientation de Pikachu correspond à un autre élement de la liste, le principe est le même, c'est seulement la commande pour réorganiser la liste qui change, et ce à cause d'un soucis d'index.
Prenons un exemple, si Pikachu regarde à gauche (<), et qu'il doit suivre le mur droit. Alors la case à sa droite, correspond dans le réferentiel d'un observateur à la case au dessus de lui. Il regardera donc d'abord en haut, puis à droite puis en bas, et enfin à gauche (voir deuxième ligne du tableau de droite).
Alors, avec l'obtention de la liste réarrangé des directions, il était aisé de coder la fonction deplacement. Cette fonction regarde pour chaque élement de la liste dans l'ordre, si l'endroit où Pikachu veut se diriger est un mur. Si c'est un mur alors elle continue son processus, mais dès qu'une case où Pikachu peut aller est détectée, on modifie les coordonnées auquelles Pikachu se situt. C'est ce changement qui simule le déplacement de Pikachu. On utilise alors l'outils break afin d'arréter la fonction.
Maintenant intéressons nous à la boucle principale du programme. Pour comprendre son fonctionnement et l'utilisation des fonctions décrites précedement, on peut la représenter sous la forme d'un schéma.
Voici ci dessous ma proposition de code commenté pour résoudre le problème Pikaptcha épisode 2.
import sys import math table = [] width, height = [int(i) for i in input().split()] # Recuperation de la taille du labyrinthe end = False depart = tuple() table2 = [] # Creation d'un tableau à deux dimentions rempli de 0 for i in range(height): line2 = [] for j in range(width): line2.append(0) table2.append(line2) for i in range(height): # On récupère le labyrinthe donné par l'énoncé line = input() table.append(line) for directions in ['<','^','>','v']: # On cherche le point de départ de Pikatchu for j in range (len(line)): if directions == line[j]: depart = (i,j,directions,False) for j in range(len(line)): # Ajout des murs au tableau à deux dimentions rempli de 0 if table[i][j] == "#": table2[i][j] = "#" side = input() # On récupère le coté par lequel Pikatchu doit longer le mur # On défini l'ordre dans lequel Pikatchu doit regarder chaque coté def cycle(direction_p,side): if side == 'R': direction = ['v','>','^','<'] # Cycle si Pikatchu doit longer le mur de droite else: direction = ['<','^','>','v'] # Cycle si Pikatchu doit longer le mur de gauche index = direction.index(direction_p) # Récupération de l'index dans le cycle de la position initiale de Pikatchu if index == 0: # Si l'index vaut 0 on reconstruit l'ordre des directions de la fin vers le début direction = direction[3:]+direction[0:3] else: # Sinon on reconstruit l'ordre en renvoyant la direction correspondant à l'index 0, à la fin de la liste des directions direction = direction[index-1:len(direction)]+direction[0:index-1] return direction # Fonction permettant à Pikachu de regarder dans chaque direction dans un certain ordre def deplacement(table, depart, side, height, width): i = depart[0] j = depart[1] direction_p = depart[2] direction = cycle(direction_p,side) # Fourni l'ordre des directions que Pikatchu doit regarder for k in direction: if k == ">" and j < width-1 and (table[i][j+1] == "0" or table[i][j+1] in direction): # Si on est pas sur le bord droit du labyrinthe on regarde à droite # et si ce n'est pas un mur on s'y déplace depart=(i, j+1,">", True) break if k == "v" and i < height-1 and (table[i+1][j] == "0" or table[i+1][j] in direction): # Si on est pas sur la derniere ligne du labyrinthe on regarde en bas # et si ce n'est pas un mur on s'y déplace depart=(i+1, j,"v", True) break if k == "<" and j > 0 and (table[i][j-1] == "0" or table[i][j-1] in direction): # Si on est pas sur le bord gauche du labyrinthe on regarde # à gauche et si ce n'est pas un mur on s'y déplace depart=(i, j-1,"<", True) break if k == "^" and i > 0 and (table[i-1][j] == "0" or table[i-1][j] in direction): # Si on est pas sur la première ligne du labyrinthe on regarde # en haut et si ce n'est pas un mur on s'y déplace depart=(i-1, j,"^", True) break return depart # Boucle principale, qui s'execute tant que Pikatchu n'est pas revenue sur sa case de départ while(end == False): depart = deplacement(table, depart, side, height, width) # Initialisation de la position de Pikatchu à chaque tour de boucle i = depart[0] j = depart[1] if depart[3] == True: # On vérifi que pikachu se soit déplacé au moins une fois table2[i][j] += 1 if table[i][j] in ('<','^','>','v'): # On vérifi si il ne retourne pas sur le point de départ end = True # Boucle qui affiche le résultat for i in range(height): for j in range(width): print(table2[i][j], end="") print("") # Retour à la ligne uniquement lorsque l'on a affiché une ligne entière du labyrinthe
Afin de valider notre réponse, le site Codingame effectue différents tests, voici ci dessous les tests les plus intéressant, qui ont permis de trouver la solution à ce problème.
> >000# > #0#00 > 00#0# side: L
> 1322# > #2#31 > 12#1#
Ce test est le premier que l'on doit passer. Il est important mais peut également être trompeur. En effet, ici Pikachu commence le labyrinthe en haut à gauche, mais ce n'est pas forcément le cas pour tout les tests. De plus, il passe sur toutes les cases, ce qui n'est pas non plus vrai pour tout les tests.
> #00###000 > 0000<0000 > 000##0000 side: R
> #11###000 > 112210000 > 111##0000
Ce test montre qu'il est possible que Pikachu ne commence pas en haut à gauche, il permet également de tester le fait que Pikachu soit orienté différement. Enfin il montre que toutes les cases ne sont pas obligatoirement parcourues.
> 0#0 > #v# > 0#0
> 0#0 > #0# > 0#0
Ce test permet de coder deux choses très importantes. Tout d'abord il permet de se rendre compte que Pikachu peut ne pas bouger. Donc, il nous permet de rajouter une condition dans le code pour vérifier si Pikachu bouge avant de remplacer sa case de départ par un 1. De plus, il montre qu'il faut initialiser toutes les cases du labyrinthe à 0, et donc qu'il est plus simple de travailler en conservant le labyrinthe d'origine, et en le copiant dans une variable que l'on pourra modifier.
Lors de la résolution de ce problème, j'ai rencontré un certain nombre de difficultés. En effet, après avoir longtemps cherché, j'avais réussi à établir un ordre dans lequel Pikachu devait regarder chaque case, mais je ne savais pas comment l'implémenter. J'ai donc eu besoin d'aide afin de coder le système d'ordre par concaténation de liste. De plus, après avoir codé la boucle permettant d'incrémenter de 1 chaque case lorsque Pikachu se déplace dessus, mon programme ne fonctionnait toujours pas. J'avais ommis un point assez important, je ne prenais pas en compte qu'après chaque déplacement, l'orientation de Pikachu pouvait changer. Alors j'ai de nouveau eu besoin d'aide afin de trouver le système de tuple permettant d'initialiser la position de Pikachu à chaque tour de boucle. La condition de retour au point de départ que j'avais codé précedement s'inscrivait dans la méthode des tuple. Alors mon programme fonctionnait enfin.
Afin de m'aider dans la réalisation du programme, j'ai visionné la vidéo de la chaine youtube Foxxpy-Mathématique et algorithmie. A la fin, j'ai séparé les différentes parties de mon code, qui était assez brouillon, en différentes fonction. Car, après avoir visionné cette vidéo, je me suis rendu compte que mon code manquait réellement de clarté, et n'était pas bien mis en forme afin d'être présenté.
J'ai choisi de présenter la solution de l'utilisateur nicola car elle est bien plus compacte que celle que je propose, et utilise un mécanisme bien différent.
Il va d'abord récupérer les variables données par le site. Lorsqu'il récupère le labyrinthe en entrée, il le modifi en remplaçant la case indiquant la position de Pikachu par un 0, et il extrait la position de Pikachu dans une variable à part. Puis, grace à un dictionnaire, il va associer l'orientation de Pikachu à un tuple. Ensuite, il associe un coté (gauche ou droite) à un autre dictionnaire composé de tuples du même type que ceux évoqués précedement.
Alors il crée la boucle principale qui récupère l'ordre exact dans lequel Pikachu doit regarder les cases adjacentes. La clé de l'ordre exacte situé dans le dictionnaire correspond au tuple récupéré au début du programme grace à l'orientation de Pikachu. Cet ordre exact est un tuple composé de tuple qui nous servirons dans l'étape suivante. En effet, on additionne aux coordonnées de Pikachu les différents tuples présents dans l'ordre exact, ce qui va nous donner des coordonnées potentielles pour le prochain déplacement de Pikachu. On va alors vérifier que ces coordonnées correspondent bien aux futures coordonnées de Pikachu. Elles vont donc passer une série de test. Il faut qu'elles soit comprises dans le labyrinthe (que ce ne soit pas des coordonnées qui dépassent les bords), et qu'elles correspondent à un passage (donc pas à un mur). Dès qu'une condition n'est pas respectée, on crée de nouvelles coordonnées avec les autres tuple du tuple "ordre exact". Si au contraire, on trouve les bonnes coordonnées, on met à jour les coordonnées de Pikachu, ainsi que son orientation (donné par un tuple). Puis on incrémente de 1 la case sur laquelle Pikachu se déplace, et la boucle recommence. Il se peut qu'aucune des propositions de coordonnées ne correspondent à un déplacement viable, alors la boucle s'arrête et on affiche le résultat. Il se peut aussi que Pikachu retourne sur le point de départ (cela doit forcément arriver à un moment donné), alors on arrête la boucle et on affiche le résultat.
Voici ci dessous le code commenté de l'utilisateur "nicola".
w,h=map(int,input().split()) p=[] for i in range(h): p.append(input()) # Ajoute les lignes du labyrinthe dans une liste D=set(p[-1])&{"<",">","v","^"} if D: d=D.pop() # Récupère l'orientation initiale de Pikachu P=(i,p[-1].index(d)) p[-1]=p[-1].replace(d,"0") # Remplace le symbole de l'orientation de Pikachu par un 0 c=input() # Récupère le coté que Pikachu doit longer init=P d={">":(0,1),"<":(0,-1),"v":(1,0),"^":(-1,0)}[d] # Récupère le code correspondant à l'orientation de Pikachu mouv={"R":{(0,1): ((1,0), (0,1), (-1,0),(0,-1)), (0,-1):((-1,0),(0,-1),(1,0), (0,1)), (1,0): ((0,-1),(1,0), (0,1), (-1,0)), (-1,0):((0,1), (-1,0),(0,-1),(1,0))}, "L":{(0,1): ((-1,0),(0,1), (1,0), (0,-1)), (0,-1):((1,0), (0,-1),(-1,0),(0,1)), (1,0): ((0,1), (1,0), (0,-1),(-1,0)), (-1,0):((0,-1),(-1,0),(0,1), (1,0))}}[c] # Récupère les ordres de déplacement possibles de Pikachu en fonction du coté qu'il doit longer while True: for m in mouv[d]: # Récupère l'ordre exact dans lequel Pikachu doit regarder les cases qui l'entoure x,y=P[0]+m[0],P[1]+m[1] # Récupère les potentielles futures coordonnées de Pikachu if not 0<=x<h: continue if not 0<=y<w: continue if p[x][y]=="#": continue d=m # Met à jour l'orientation de Pikachu P=(x,y) # Met à jour les coordonnées de Pikachu p[x]=p[x][:y]+str(int(p[x][y])+1)+p[x][y+1:] # Stock le résultat obtenu break else: break if P==init: # Test au cas où Pikachu n'ai pas bougé break print("\n".join(p)) # Affiche le résultat
Ce travail m'a appris à coder un programme avec de nombreuses fonctions et à ne pas se baser uniquement sur un test pour coder un résultat. En effet, lorsque j'ai voulu résoudre ce problème je me suis uniquement basé sur le premier test ce qui m'a fait défaut par la suite, et m'a obligé à recommencer. Il m'a aussi permi d'approfondir d'avantage l'aspect logique, puisqu'il fallait trouver les cycles correspondant aux différents cas de figure. J'ai également trouver intéressant le fait de devoir simuler le déplacement d'un personnage de manière un minimum élaborée (prise en compte de la direction dans laquelle il regarde), car j'avais peu traité ce genre de problèmes auparavent. Enfin, la solution de nicola avec les dictionnaires m'a permi de revoir l'utilisation des dictionnaires ainsi que leurs possibilités dans un cadre un peu plus concret qu'un simple exercice d'affectation de valeurs.