#include #include #include #include #include "../../lib/aoc.h" enum Direction { UP, LEFT, RIGHT, DOWN }; typedef struct Position { int x; int y; } Position; typedef struct Map { char *data; int width; int height; Position robot; } Map; char char_at_position(Map *map, Position p) { return map->data[p.x + (map->width * p.y)]; } void set_char_at_position(Map *map, Position p, char c) { map->data[p.x + (map->width * p.y)] = c; } bool move(Map *map, Position p, char dir) { Position target; switch (dir) { case '^': target.x = p.x; target.y = p.y - 1; break; case '<': target.x = p.x - 1; target.y = p.y; break; case '>': target.x = p.x + 1; target.y = p.y; break; case 'v': target.x = p.x; target.y = p.y + 1; break; } // printf("Moving from [%d,%d] to [%d,%d]\n", p.x, p.y, target.x, target.y); bool can_move; switch (char_at_position(map, target)) { case '#': can_move = false; break; case '.': can_move = true; break; case 'O': can_move = move(map, target, dir); break; } if (can_move) { char mover = char_at_position(map, p); if (mover == '@') { map->robot.x = target.x; map->robot.y = target.y; } set_char_at_position(map, target, mover); set_char_at_position(map, p, '.'); } return can_move; } void execute_instruction(Map *m, char inst) { if (inst == '\n') return; move(m, m->robot, inst); } int main() { char *input = aoc_read_input(); char *split = strstr(input, "\n\n"); split[1] = '\0'; char *instructions = split + 2; int instructions_length = strlen(instructions); int robot_index = strchr(input, '@') - input; Map m; m.data = input; m.width = strchr(input, '\n') - input + 1; m.height = strlen(input) / m.width; m.robot.x = robot_index % m.width; m.robot.y = robot_index / m.width; for (int i = 0; i < instructions_length; i++) { execute_instruction(&m, instructions[i]); } Position p; int total = 0; for (int i = 0; i < strlen(input); i++) { p.x = i % m.width; p.y = i / m.width; if (char_at_position(&m, p) == 'O') total += ((100 * p.y) + p.x); } printf("Part 1: %d\n", total); aoc_free(); exit(0); }