diff --git a/c/2024/15/warehouse_woes.c b/c/2024/15/warehouse_woes.c new file mode 100644 index 0000000..dbb2336 --- /dev/null +++ b/c/2024/15/warehouse_woes.c @@ -0,0 +1,115 @@ +#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); +}