diff --git a/c/2024/6/guard_gallivant.c b/c/2024/6/guard_gallivant.c index f528496..df39068 100644 --- a/c/2024/6/guard_gallivant.c +++ b/c/2024/6/guard_gallivant.c @@ -5,6 +5,8 @@ #include "../../lib/aoc.h" +#define MAX_LOOP_LENGTH 8000 + typedef enum Direction { RIGHT, UP, LEFT, DOWN } Direction; typedef struct Position { @@ -18,6 +20,9 @@ typedef struct Game { int height; Position guard; Direction guard_direction; + Position guard_start; + Direction guard_start_direction; + int positions[10000]; int position_count; } Game; @@ -61,7 +66,7 @@ void turn_guard(Game *game) { game->guard_direction = new_direction; } -void move_guard(Game *game) { +void move_guard(Game *game, bool deface) { Position target; target.x = game->guard.x; target.y = game->guard.y; @@ -82,9 +87,10 @@ void move_guard(Game *game) { if (position_has_obstacle(game, target)) turn_guard(game); else { - if (game->map[index_from_position(game, game->guard)] == '.') { - game->map[index_from_position(game, game->guard)] = 'X'; - game->position_count++; + int index = index_from_position(game, game->guard); + if (deface && game->map[index] == '.') { + game->map[index] = 'X'; + game->positions[game->position_count++] = index; } game->guard.x = target.x; @@ -93,9 +99,10 @@ void move_guard(Game *game) { } int main() { - char *line; + char *dirty_map = aoc_read_input(); + Game game; - game.map = aoc_read_input(); + game.map = dirty_map; game.width = strchr(game.map, '\n') - game.map + 1; game.height = strlen(game.map) / game.width; game.position_count = 0; @@ -104,15 +111,57 @@ int main() { game.map[i] = '.'; game.guard = position_from_index(&game, i); game.guard_direction = UP; + game.guard_start = game.guard; + game.guard_start_direction = game.guard_direction; break; } } + char *clean_map = malloc(strlen(dirty_map) + 1); + strcpy(clean_map, dirty_map); + + Game time_travel_game; + time_travel_game.map = clean_map; + time_travel_game.width = game.width; + time_travel_game.height = game.height; + time_travel_game.position_count = 0; + time_travel_game.guard = game.guard; + time_travel_game.guard_direction = game.guard_direction; + time_travel_game.guard_start = game.guard; + time_travel_game.guard_start_direction = game.guard_direction; while (guard_inbounds(&game)) { - move_guard(&game); + move_guard(&game, true); + } + printf("Part 1: %d\n", game.position_count); + + int loop_count = 0; + for (int i = 0; i < game.position_count; i++) { + time_travel_game.map[game.positions[i]] = '#'; + int gsx = time_travel_game.guard_start.x; + int gsy = time_travel_game.guard_start.y; + int gsd = time_travel_game.guard_start_direction; + time_travel_game.guard = time_travel_game.guard_start; + time_travel_game.guard_direction = time_travel_game.guard_start_direction; + int j = 0; + while (guard_inbounds(&time_travel_game)) { + move_guard(&time_travel_game, false); + if (time_travel_game.guard.x == gsx && + time_travel_game.guard.y == gsy && + time_travel_game.guard_direction == gsd) { + loop_count++; + break; + } + j++; + if (j % MAX_LOOP_LENGTH == 0) { + gsx = time_travel_game.guard.x; + gsy = time_travel_game.guard.y; + gsd = time_travel_game.guard_direction; + } + } + time_travel_game.map[game.positions[i]] = '.'; } - printf("Part 1: %d\n", game.position_count); + printf("Part 2: %d\n", loop_count); aoc_free(); return 0;