The winners of The Last Crusade, Gangrene, NewbOo and azukun, return to their code and tell us how they went about saving the skin of Indy.
Gangrene‘s Debrief:
(1st place on the podium | France | Python | 2:22:54)
For the first task, I stored the different rooms in an 8×3 table (8 rooms, 3 entrances top, left, right). Each cell of this table indicates whether there is an exit and, if applicable, the calculation needed to obtain the new coordinates.
For the first task, it was therefore sufficient to read the cell corresponding to Indiana’s current coordinates.For the second task, one now needed to find a path that did not yet exist.
I decided to perform a depth-first search. I travel as far as the current path permits. As soon as I reach a room that does not provide an exit, I look, if possible, to turn it, and if not I go back. Of course, to avoid losing turns, I am careful to first test the room without turning it, then pivoting it a sole notch to the left or right, and finally turning it completely as a last resort. I always keep in mind the number of turns I have to reach this room (number of turns of moving minus the number of pivots already made).
When the exit is reached, I return the length of my recursion while sending back as a result the first pivot made, and the number of turns I have before doing it.
The result is then analyzed.
If I have turns at my disposal and only boulders are present, then I like to occupy myself with these.
At this stage, the ordeal had already started two hours ago, and I thought to myself that given the previous challenges, the top spots had already been taken. I thus do not go for subtleties. I test the boulders in the order they appear. For each one I calculate its path until the first rotating room. If this room provides an exit, I turn it to block the stone (this is possible in 1 stroke regardless of the room and its position), if not I test the next stone.
If all of the stones around are already blocked, I pivot the previously taken room to free Indiana’s passage.
If no room is to be moved, nothing to do but WAIT, it is won.
My code isn’t perfect, and I realize this even more while analyzing it in order to write this. For example, if a room needs to be turned by a notch and the next by two, my function will return that I need one turn to rotate the first room, while another two will be needed to start the movement of the following room.
The situation posed with the boulders could have been much more complex, forcing Indiana to follow one route and not another, a trap into which I would have fallen.
Once again, CodinGame has presented us a great challenge, very complex on paper, but fortunately simplified by the situations given.
———–
(2nd place on the podium | France | PHP | 2:34:57) Best to admit it right away: I was initially a little lost. Unlike the previous editions where the playing field was globally fixed, here it was variable and one didn’t have control over poor Indy, which ultimately meant reversing the classic path-searching problems. Fortunately, the first exercise tended to put us on the right track by teaching us to simulate the movement of Indy (and thus of the boulders as well).
Definition of constants
The boulders
The final word I was really very surprised to finish 2nd with such a “long” time compared with previous editions, especially with some time foolishly lost on my tree traversal in which, originally, I never tested the rotations if the WAIT was working… but whatever the ranking, I would in any case have taken much pleasure in saving Indy. Thanks to CodinGame for the always-original subjects (and the “Dark mode” of the IDE ^_^).
(3rd place on the podium | Russia | C# | 2:39:01)
Level 1: For the warming up task one just needed to carefully implement Indy’s movement through all room types for all possible directions, I did it with a 14×3 matrix:
{ -1, -1, -1 },
{ 1, 1, 1 },
{ 2, -1, 0 },
{ -1, 1, -1 },
{ -2, 0, 1 },
{ 1, 2, -2 },
{ 2, -2, 0 },
{ -1, 1, 1 },
{ 1, -1, 1 },
{ 1, 1, -1 },
{ -2, 0, -1 },
{ -1, 2, -2 },
{ -1, -1, 1 },
{ 1, -1, -1 },
};
Having matrix like this, each turn I do following to calculate new Indy’s coordinates:
int w = way[tunnel[r][c], p];
r += dr[w];
c += dc[w];
Level 2: So we’ve got a labyrinth, but instead of controlling the player, we control the labyrinth itself – another nice task from CodinGame! While sounds intimidating, we do as usual iterate through possible moves until we reach exit. I did it with a simple recursive DFS. But what took me and other competitors so long – is abundance of details requiring very careful implementation and… rocks! I’ve spent more than an hour to pass the last two tests. While they move only from right to left in a very simple tunnel, my code required a lot of modifications – a notable one is to rotate rooms of type 6 and 8 to type 9, not type 7 in order to block some rocks.
Anyway, kudos to CodinGame team for yet another exciting coding feast, looking forward to Shadows of the Knight!