diff --git a/aoc/aoc.h b/aoc/aoc.h index d82d035..e584bef 100644 --- a/aoc/aoc.h +++ b/aoc/aoc.h @@ -28,6 +28,10 @@ grid_at(Grid *grid, i32 x, i32 y) { return grid->grid[y * grid->width + x]; } +static inline bool +grid_contains(Grid *grid, i32 x, i32 y) { + return x >= 0 && y >= 0 && x < grid->width && y < grid->height; +} #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #include @@ -53,6 +57,12 @@ typedef double f64; #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define CLAMP(x, lo, hi) ((x) < (lo) ? (lo) : (x) > (hi) ? (hi) : (x)) +#define MIN3(a, b, c) MIN(MIN(a, b), c) +#define MAX3(a, b, c) MAX(MAX(a, b), c) + +#define MIN4(a, b, c, d) MIN(MIN(a, b), MIN(c, d)) +#define MAX4(a, b, c, d) MAX(MAX(a, b), MAX(c, d)) + #define Kilobytes(x) ((u64) (x) << 10) #define Megabytes(x) ((u64) (x) << 20) #define Gigabytes(x) ((u64) (x) << 30) diff --git a/day-16/input.txt b/day-16/input.txt new file mode 100644 index 0000000..ebe53c5 --- /dev/null +++ b/day-16/input.txt @@ -0,0 +1,141 @@ +############################################################################################################################################# +#.......................#.......#.............#...........#.....#...#.......#.........#...................................#.......#........E# +#.#.#######.###.#########.#.###.###.#.#.#####.#######.###.###.#.#.###.#####.#.#####.#.#.#####.###.#.###.#####.#.#######.###.#####.#.#######.# +#.#.#.................................#.....#...#...#...#.....#...#.......#...#...#.#.#.#...#.....#...#.#...#.#...#...#...#...#.#...#.....#.# +#.###.#.#.#######.#########.#.###.#.###.###.###.#.#.###.#.#######.#.###########.#.#.#.#.#.#.#####.###.###.#.#.###.#.#.#.#.#.#.#.#####.#####.# +#.....#.#.#.......#...#...#.#.#...#...#...#...#...#.....#.........#...#...#...#.#...#.#...#.#.......#.....#.#.....#.#.#.#.......#.....#...#.# +#.#####.#.#.#######.#.###.#.#.#.#####.#####.#.###########.#########.###.#.#.#.#.#.###.#.###.#.###.#.#######.#.#####.#.#####.###.###.#.#.#.#.# +#.....#...#.#.......#.....#.#...#...#.....#.#...........#...#.......#...#...#...#...#.......#.#...#.......#.#.....#.#.......................# +#########.#.#.#########.###.#.###.#.#####.###########.#.#.###.#######.#############.###.#####.#.#.#########.#.#####.#######.#.#######.#.##### +#.........#.#...#.......#.....#...#...#.............#.#.............#...#...................#...#.....#.....#.....#...#.#...#.........#.....# +#.###.###.#.#.#.#######.#.#####.#####.#.###########.#####.#.#####.#####.#.#######.#####.###.#.###.###.#.#####.###.#.#.#.#.#.###.###########.# +#.#...#.....#.#.......#.#.......#...#.#.#.....#...#.......#.#...#.#.....#.#.......#.......#.........#.#.#.......#.#.#.#.#.....#.............# +#.#.###.#.###.#######.#.#########.###.#.#.###.#.#.#######.#.#.#.#.#.#####.#####.###.###.#.###.#####.#.#.#.###.#.#.#.#.#.###.#.#.###.#######.# +#.#...#.#...#...#.......#.....#...#...#.#...#...#...#.....#.#.#.#.#.#...................#...#.........#.#...#...#.#...#.#.....#.............# +#.#####.#.#.###.#.#####.#.###.#.#.#.#####.#########.#.#######.#.#.#.###.#####.#.###.#.#.###.#.#######.#.#####.###.#.###.#.#.###.#####.###.#.# +#.....#.#.#...#.#.#...#.#.#.#...#.#.......#...#.....#.........#.#.#...#.....#.#.#...#.#...#.#.....#...#.#.....#...#...#.#.....#.#.....#.#.#.# +#####.#.#.###.#.#.#.#.#.#.#.#####.#########.#.#.#######.###.###.#####.#####.#.###.###.###.#.#.###.#.###.#.#####.#####.#.#####.###.#####.#.#.# +#.....#.#.#...#.#...#.#...#.....#.#.....#...#...#...........#.#.#...#.#...#.....#.#.....#.#...#.#.#.#.#.#...#...#.....#...#...#...#.#.....#.# +#.#.###.#.#####.#####.#######.#.#.###.###.#######.###########.#.#.#.#.###.#.###.#.#.#.###.#####.#.#.#.#.#.#.###.#.#####.###.###.###.#.#####.# +#.#.#...#.....#.....#.#.......#.#...#...................#.....#...#.#.#...#.#.#.#...#.#.........#.#...#.#.#.......#.....#...#...#...#...#...# +#.#.#.###.###.#####.#.#.###########.#.#.#########.#####.#.###.#####.#.#.###.#.#.###.#.#.#####.###.#.###.#.###.#########.#.###.###.#####.#.#.# +#.#.#.#.#...#.#...#.#.#...#.........#.#...#.....#.....#.#...#.......#.#.#.....#.....#.#.#.....#...#.#...#.#.....#.......#.#...#.#.....#...#.# +#.###.#.###.#.#.#.#.#.#.#.#.###########.#.#.###.#####.#.###########.#.#.#.#########.###.#.###.#.#####.###.#.###.#.#.#.###.###.#.#.#.#######.# +#.....#.....#...#...#.#.#...#...........#.#.#.#.#.....#.....#.....#...#...#.......#.....#.....#.......#...#.#...#.#.#.....#...#.#.#.......#.# +#.###########.#######.#.#####.###.#####.###.#.#.###########.#.###.#####.###.#####.#######.#############.#.#.#.#.#.#.###.###.###.#.#####.###.# +#.....#...............#...#.....#...#...#...#...#...#.......#...#.#...#.#...#.#...#.....#.....#.#.....#.#.#.#.#...#...#.....#.....#...#.....# +#.#.#.#.#####.###########.#.#####.#.#.###.###.###.#.#.#.#######.#.#.#.###.###.#.###.#.#######.#.#.###.#.#.#.#.#######.#.#.###.###.#.#####.### +#.......................#.#.#...#.#.#.....#...#...#...#.#.......#...#...#.#...#.#.#.#.........#.....#.....#.#.....#.#...#...#.#.....#...#...# +#.#.#.#####.#.###.#######.#.#.#.###.###.#.#.#####.#######.###########.#.#.#.#.#.#.#.###############.#.#.###.#####.#.#####.#.#.#.#####.#.##### +#.#.#.....#.#...#.#.......#.#.#.#...#...#.#.....#...#.....#...........#.....#.#.#.#.......#.........#...#...#...#.#.....#.#.#.....#...#.....# +#.#.#####.###.#.#.#.#########.#.#.###.###.#####.###.#.#####.#####.#############.#.#######.#.#.###.#####.#.#.#.#.#.#.#####.#.#####.#.#######.# +#.......#.#...#.#.#...#.....#.#...#.....#.#...#.....#...#.#...#.#.#.............#.........#...#.#.....#.#.#.#.#.#.#.#...#.#...#...#.#.......# +#.#.#.#.#.#.#.#.#.###.#.#.#.#.###.#######.#.#.#####.###.#.#.#.#.#.#.#########.#.#########.#.###.#####.#.#.###.#.#.#.#.#.#.###.#.###.#####.### +#.....#.#...#...#.....#.#.#.#.#...#.......#.#.....#.#.#.#...#.#...#...#...#...#.........#.#.......#.#.#.#.....#.#...#.#...#.#.#.#.#.....#.#.# +#.#.###.#########.#######.#.#.#####.#####.#.#.#####.#.#.###.#.#######.#.#.#.###.#.#####.#.#.#.#.#.#.#.#########.#####.#####.#.#.#.#####.#.#.# +#.#...#.#.#.....#.#.....#.#...#...#.#.......#.........#...#.#.......#.#.#.#.#...#.....#.#.#.#.#.#.#.#.#...........#...#.......#.......#.#...# +#.#.#.#.#.#.###.#.#.###.#.#####.#.#.###########.#########.#.###.###.#.#.#.###.###.#.###.#.###.#.#.#.#.#.#####.###.#.###.###############.###.# +#...............#...#.#.#...#...#...#.........#.......#...#.#.....#.#.#.#.#.......#.#...#.#...#.#...#.#.#.#.......#...................#.#.#.# +#.#.#.#.#.#.#.#######.#.###.#.#######.#####.#.#.#.###.#.###.#.#.###.#.#.#.#.#########.###.#.#.#.###.#.#.#.#.#####.#.#.###########.#.#.#.#.#.# +#.#.#...#...#.#...........#.#.........#...#.#.#.#...#.#...#...#.#...#.#.#.#.#...........#...#.....#.#.#.....#...#.#...#.........#...#...#...# +#.#.#.###.###.#.###.#####.#.###########.#.###.#####.#.###.#####.#.#.#.#.#.#.#.#####.#.#.#####.###.###.#.#####.#.#.###.###.#.#############.### +#...#.#...#...#...#.#.....#...#.....#...#...#.....#.#.........#.#.#.#...#...#.#...#.#.#...#.#.#.......#.......#.#...#...#.#.........#.....#.# +#.###.#####.#.###.#.#.#####.#.#.###.#.#####.###.###.#.#######.#.#.###.###.###.#.#.#.#####.#.#.#.#.#.#####.#####.#.#####.#.#######.###.#####.# +#.#.#.......#...#.#.#...#.......#...#.....#.....#...#.....#...#.#.#.....#.#...#.#.#.....#.#...#.#...#...#.#.....#.#.....#.....#...#...#...#.# +#.#.###.#########.#.###.#.###.###.#.#####.#######.###.###.###.###.#.#.#.#.#.###.#######.#.###.#.#.###.#.###.###.###.#########.#.#.#.###.#.#.# +#.#...............#.......#.......#...#.#.........#.#.#.....#.....#.#...#.#.#...#.....#.#...#.#...#...#.....#.#.#...#...........#.#.#...#...# +#.#.#.###.#.#.#####.#######.#######.#.#.###.#######.#.#####.###.###.#.#.###.#.###.#.###.###.#.#####.#########.#.#.###########.#.###.#.#####.# +#.#.#.#.#.#...#...#.......#...#.....#.#.......#.....#...#...#.#.#...#.......#.....#.....#...#.....#.#.......#...#...........#.#...#.#...#.#.# +#.#.#.#.#.#####.#########.###.###.###.#.#.###.#####.###.#.###.#.#.#############.#########.#####.#.#.#####.#.#.#############.#.###.#.#.#.#.#.# +#.#...#.#.#...#.#.......#...#.....#.#.#.#.#.#.......#...#.#.#...#...#...#.....#...........#...#...#...#...#.#.#.......#...#.#.#.#...#.#.#...# +#.###.#.#.#.#.#.#.#####.#.#.#######.#.###.#.###.#.###.###.#.#.#####.#.#.#.###.#######.#.###.###.#####.#.#.#.#.###.###.#.###.#.#.#######.#.### +#...#...#.......#.#.....#.#.#.......#.....#...#.#...#.#...#...#.....#.#...#.........#...#.....#.#.......#.#.......#.#.#.#...#...#.....#.#...# +#.#.#######.#####.#.#####.#.#.#####.#######.###.###.#.#.#######.#####.#.###########.#.#######.#.###.#.#.#.#########.#.#.#.#####.#.###.#.###.# +#.#...#.....#.....#.#.....#.#.#...#.........#.......#.#.......#.....#.#.#...#.....#.#.#...#...#.....#.#.#...#.......#...#.........#...#.#...# +#.###.#.#####.#.###.#.#.###.#.#.#.###.#######.#.#####.#######.#.###.#.###.#.#.#####.#.#.#.#.#########.#.###.###.#.#####.#.#########.###.#.### +#.#.#...#.....#.....#.#.....#.#.#.#...#.......#...#.......#.#.#.#...#...#.#.#.......#.#.#.#.......#...#.#.....#.#.......#.....#.#...#...#...# +#.#.#####.#####.#####.#####.#.#.#.#.###.#.#####.#.#.###.#.#.#.#.#.#####.#.#.#.#########.#.###.#.###.###.#####.#.#######.###.#.#.#.#####.###.# +#...#...#.#.#...#.#.......#.#...#.#...#...#.....#.#.#...#...#.#...#...#...#.#.......#...#.......#.....#...#...#...#...#.#.#...#.#.#.....#...# +###.#.#.#.#.#.###.#.#####.#####.#.###.###.#.#####.#.#.#.#.###.#.###.#.#####.#.#####.#.#####.#.#.#.#######.#.#######.#.#.#.#.###.#.###.###.### +#...#.#.#.#...#...#.....#...#.....#.#.....#.#...#.#.#...#.#...#.#...#.......#...#...#.....#...#.#...#.....#.#.......#.#...#...#.#.....#.#.#.# +#.#####.#.#.#####.#.#######.#.#####.#######.#.#.#.#.#.#.#.#.###.#.###########.###.###.###.#.###.###.#.#####.#.#####.#.#######.#.#######.#.#.# +#.#...#.#.#.#.....#.#.......#.#.#.......#.#.#.#.....#.#...#.....#.....#.#.........#.#.#...#...#.#...#.#.#...#...#.............#.........#...# +#.#.#.#.#.#.###.###.#.#.#.###.#.#.#.###.#.#.###########.#######.#####.#.#.#########.#.#.#####.#.#.###.#.#.#####.#############.#.#####.#.###.# +#...#.#.............#.#.......#.#.#.#.....#...#.......#...#...#.#.#...#.#.#...#.......#...#.#.#...#...#.#.....#.#...#.........#.............# +#.###.#.#.###.#.#####.#.#######.#.#.#########.#.#####.#.#.#.#.#.#.#.###.#.#.###.#########.#.#.###.#.###.#####.#.#.#.#.#######.#.#.#.#.#.#.### +#...#.#.#.#...#.#...#.#.....#.....#...#.......#...#...#.#.#.#.....#...#...#...#.#...#.....#.#...#.#.#.......#.#.#.#.#...#.....#...#.#.#.#.#.# +#.#.#.#.#.#.#####.#.#.#####.#.#######.#.###.#####.#.#####.#.#########.#.#####.#.#.#.#.#####.###.#.#.#.###.###.#.#.#.###.#########.###.###.#.# +#.#.....#.#.....#.#.#.#...#.#.#.#...#.#.#...#.....#.....#.......#...#.#.....#.....#.#.#...#...#.#...#...#.....#...#...#...........#...#...#.# +#########.#####.#.#.#.#.#.#.#.#.#.#.#.#.###.#.#########.#########.#.#.#####.#######.#.#.#.#.###.###.###.#############.#.###########.#.#.###.# +#...#.....#.#.....#...#.#...#...#.#...#...#.#.........#.....#.....#.#.#...#.......#.#...#.#...#.....#.#.#...#.........#...........#.#.#.#...# +#.#.#.#####.#.#########.#####.###.#######.###########.#####.#.#####.#.#.#.#.#####.#######.#.#.#######.#.#.#.###.###.#####.#.#####.#.###.#.#.# +#.#...#.#.....#.#.......#.....#...#.....#...#.....#.......#.....#.....#.#.#...#...#.......#.#...#.......#.#...#.#.......#.#.#.......#...#...# +#.#####.#.#####.#.###########.#.#.#.###.###.#.###.#.#############.#.#.###.#.#.#.###.###.###.#.###.#.#####.###.#.#####.#.#.#.#######.#.###.### +#.#...#.........#.#.........#.#.#.#.#.....#.#...#.#...#.........#...#...#.#.#.#.#...#.....#.#...#.#.......#.#.#...#...#...#.......#.#.#.....# +#.#.#.#.#########.#.#####.#.###.###.#.#####.###.#.#.###.#######.#.#.#.###.#.#.#.#.#######.#.###.#.#.#.#####.#.###.#.#.#########.#.#.#.#.###.# +#.....#...#.....#.#...#...#...#...#.#.....#.#...#.#.#...#.........#.#...#...#.#.#.#...#...#.#.#...#.#.#.....#...#...#.#.......#.#.#.#.#...#.# +#.###.#####.###.#.#####.#####.###.#.#####.#.#.###.#.#.#################.#####.#.#.#.#.#.###.#.#####.#.#.#######.#.###.#.#####.#.#.###.#####.# +#...#.........#.#.......#.......#.....#...#.#...#...#...........#.....#.......#.#...#.#.......#...#.#.#.......#.#...#.........#.#.....#...#.# +#############.#.#####.#########.#######.#.#.#.#.#######.#######.#.###.#########.###.#.#######.#.#.#.#.#####.#.#.#########.#####.#######.#.#.# +#...#...#...#.#.......#.............#...#.#.....#.........#...#.....#.....#...#...#.......#.#.#.#.#.#.#.....#.#.#.........#...#.#.....#.#.#.# +#.#.#.#.#.#.###.#######.###.#.#####.#.###.#########.#####.###.#####.#####.#.#.###.#####.#.#.#.#.#.###.#.#####.#.#.###########.#.###.#.#.#.#.# +#.#...#...#...#.#.#.......#...#.......#...#...#.....#.....#...#.#.......#...#...#.#.......#.#...#.....#.....#.#...........#...#.....#...#.#.# +#.###########.#.#.#.#####.#.###.#####.#.###.#.###.#####.###.#.#.#.#####.#####.###.#.#######.#.###########.#.#.#####.#####.#.#.###########.#.# +#...........#.#...#...#.#...#...#.....#...#.#...#.#...#.....#.#.....#...#...#...#...#.....#.....#.........#...#.....#.....#.#.#.....#.#...#.# +#######.###.#.#######.#.#.###.#####.#####.#.###.#.#.#.#######.#######.#.#.#.###.#####.###.#####.#.#####.###.#####.#.#.#####.#.#.#.#.#.#.###.# +#.....#...#.#.........#.#.#.#.#.....#...#...#.....#.#...#.....#...#...#...#.........#...#...#...#.#...#.#.#.....#.#.#.......#.#.#.#...#.#...# +#.###.#####.###########.#.#.#.#.#####.#.#.###.#####.###.#####.#.#.#.#####.###.###.#.#.#.###.#.###.#.#.#.#.#####.###.#########.#.#.#####.#.### +#.#.....#...#...#.........#.....#...#.#...#.......#...#.....#...#...#...#...#.....#.#.#...#...#...#.#.#.#.......#...#.....#...#.#.......#...# +#.#####.#.###.###.#################.#.#.#.#.#####.#.#.#####.#.#.#####.#.#.#.#######.#.###.###.#.#####.#.#.#######.###.###.#####.#######.###.# +#.................#.......#...#...#...#...#.#.#...#.#...#...#.#.....#.#.#.#.#.#.....#...#.#...#.#.....#.#.....#...#...#.#.#.....#.#.......#.# +#.#.#.#####.#.#.#.#.#.###.#.#.#.#.#########.#.#.###.###.###.#.#.###.#.#.###.#.#.###.###.#.#####.#.#.#.#.###.#.###.#.###.#.#.#####.#.#.#.#.#.# +#.#.#.#...#...#...#.#...#...#...#.........#.#.#...#...#...#.#.#.......#.....#.#.#.......#.#.....#.#.#.#.....#...#.#.#...#.#.#...#...#...#...# +#.#.###.#.#.#.#######.#.#################.#.#.#.#.#######.#.###.#############.#.#.#######.#.#######.#######.###.#.#.#.#.#.#.#.#.###.###.###.# +#.#.....#.#.#.......#.#.....#.#.....#...#...#...#.#.....#.#.....#.......#...#.......#...#.#.......#.......#.#.......#.#.#...#.#...#.#...#...# +#.#######.#.#.###.#.#.#####.#.#.###.#.#.#####.#.#.#.###.#.#######.#####.#.###.#######.#.#.#######.#####.#.#.#######.#.#.#####.###.###.#.#.### +#.......#.#.......#.#...#.#.#.....#...#.#.....#.#.....#.#.#...#.....#...#...#.#.......#.......#...#.....#.#.........#.#.....................# +#.#######.###.#.###.###.#.#.#####.#####.#.#####.#.#.#.#.#.#.#.#.#####.###.#.#.#.#############.#.###.#####.###########.###.#####.#.#.###.###.# +#.#.......#.......#.#.#...#...#.#...#.#.#...#.#.....#.....#.#...#.....#...#.#...#...#.......#.#.#...#...#.#.....#.....#.#.#...#.....#.......# +#.#.#####.#.#.###.#.#.###.#.#.#.###.#.#.###.#.#########.###.#####.#########.#####.###.#####.#.#.###.#.#.#.###.#.#.#####.#.#.#.#.#######.#.#.# +#.#...#...#.....#.#.#.#...#.#.#.......#.......#.......#.#.....#...#...#...........#...#...#...#.#...#.#.....#.#.#.#.#...#.#.#...#.....#.....# +#.###.###.#.#.#.#.#.#.#.###.#.#.#########.#####.#####.###.#####.#.#.#.#.###.#####.#.#####.#####.#.#####.###.#.###.#.#.#.#.#####.#.###.#.###.# +#...#.#.......#.#...#.......#.#...#.....#.#.#...#...#.....#.....#.#.#.#...#.....#.#.#.....#.....#.....#...#.#.....#...#.#.....#.#...#.....#.# +###.#.#.###.#.#.#####.#####.#.###.#.###.#.#.#.#####.#######.#.#####.#.###.#####.#.#.#.#####.###.#####.###.#.#.#########.#####.###.#.###.#.#.# +#...#.#.#...#.............#.#.#...#...#.#...#.#.....#...#...#.#.....#.#...#.......#.#...#...#.........#...#.#...#.......#...#...#...#...#.#.# +#####.#.#.#.#.#######.###.###.#.#####.#.#####.###.#.###.#.#####.#####.#.###.#####.#.###.#.###.#########.###.###.###.###.###.###.#.###.#.#.#.# +#.....#.#.#.......#...#.......#...#...#.....#.....#.....#...#.....#...#.#...#...#.#.....#.#...#.............#.#...#.#.........#.....#.#...#.# +#.#####.#.#.#.###.#.###########.###.#######.###.#######.###.#.###.#.###.###.#.#.#######.#.#.###.#############.###.#.#####.#######.###.#.###.# +#.#.......#...#...#.#.....#...#.#...#.......#.#.......#...#.#.#...#...#...#.#.#...#...#.#...#.#.#...........#.....#.....#.#...#.......#...#.# +#.###.#####.#.#.###.#.###.#.#.#.#.###.#####.#.#.#####.###.#.#.#.#.###.###.#.#.###.#.#.#.#####.#.###.###.###.#.#####.###.###.#.#.#.#######.#.# +#...#.....#.#.#.....#.#.#...#.#.#.#.#...#.#.#...#.......#.....#.#...#...#.......#.#.#.#.#...#.#.....#.......#.....#...#.#...#.#.#.......#.#.# +#.#.#.#####.#.###.###.#.#####.#.#.#.###.#.#.#####.#####.#.#####.#######.#######.#.#.#.#.#.#.#.###.#.###.#########.#####.#.###.#.###.###.#.#.# +#.#.#.#.....#.#...#...#.....#.#.#.....#.#.....#...#...#.#.#...........#.#...#...#...#.....#.....#.#...#.#.......#...#...#.#...#...#...#...#.# +#.#.#.#.#####.###.#.#######.#.#######.#.#####.#.###.###.#.#######.###.#.#.#.#####.#############.#.###.#.#.###.#.###.#.#.#.###.###.###.#####.# +#.#.#.#.#...#...#.#.#.......#...........#...#...#.......#.......#...#.....#.....#.#.....#...........#.#.#...#.#...#...#.#...#.#.............# +#.#.###.###.###.#.#.#.#################.#.#.#####.#############.#####.#########.###.###.#.#########.#.###.###.#.#######.###.#.#.###.###.#.#.# +#.#...#...#...#.#...#...........#.....#.#.#.....#.#...........#...........#...#...#.....#...#.......#.....#.....#.......#...#...#...#...#...# +#####.###.#.#.#.###.#.#########.#.###.#.#.#####.#.#.###.#.#####.#########.#.#.###.#.###.###.#.#######.#####.###.#.#######.#########.#.#.###.# +#.......#...#.......#.....#.....#...#.#.#.#...#.#.#.#.#.#.........#.....#.#.#...#.#.#...#...#...#.........#.#...#.......#...#.......#.#...#.# +#.###.#######.###########.#.#######.#.#.#.###.#.###.#.#.###.#.#####.#.#.#.###.#.#.#.#.###.#####.#.#####.#.#.###########.###.#.#####.#.#.#.#.# +#.#.#.#.....#.#.#.........#.#.......#...#.....#...#.#.....#.#.......#.#.#.....#.#...#...#.#.....#.......#.#...........#.#.#.#.....#.#.#.#...# +#.#.#.#.###.#.#.#.#########.#.#####.#.#.#####.###.#.#.###.#.#########.#########.#######.###.#############.###########.#.#.#.###.#.#.#.#.###.# +#.#...#.#.#...#...#.....#...#.#.#...#.......#.#...#.....#...#.......#.........#.#.......#...#...#.........#...#.......#.#.#...#.#...#...#.#.# +#.###.#.#.#########.###.#.#.#.#.#.###.#.#####.#.###.#.#####.#.###.###########.#.#.#####.#.#####.#.###########.#.###.###.#.###.#.#.#####.#.#.# +#...#.#.#.....#.....#.#...#.#.#...#.....#.....#.....#.....#.....#.........#...#.#.....#.#.....#...#.....#.....#.#...#.......#.#.#.....#.....# +#.#.###.#.###.#.#####.###.#.#.###.#.###.#.#############.#.#.#######.#.#####.###.#####.#.#####.#.#####.#.###.###.#####.#######.#.#######.###.# +#.#...#.#...#.#.....#.....#.#...#.#.#...#.....#.........#.#.....#...#.#...#...#...#...#.#.#...#.......#...#...#.......#.......#.......#.....# +#.###.#.###.#.#.###.#.###.#.###.###.#.#######.#.#######.#.#.###.#.###.#.#.#.#.###.#.###.#.#.#############.###.#########.#######.#####.#.###.# +#.#...#.....#.#...#.#...#...#.#.#...#.......#...#.#.....#...#.#.#.#...#.#...#.....#.#.......................#.........#.......#.....#...#...# +###.#.#######.###.#.#.#####.#.#.#.#####.###.#####.#.#.#.#####.#.#.###.#.###.###.#.#.#.#.#.#####.#.#.#.#.###.#.#######.#######.#####.#.#.#.#.# +#...#.......#...#.#.......#...#.#.#...#.#.#.......#.#...........#...#.#...........#.#...#.......#.#.#.#...#.#.#.....#.#...#...#.#...........# +#.###.#########.###.#####.#####.#.###.#.#.#.#######.###.#####.#####.#.###.#.###.#.#.#.###.###.#.#.#.#.#.###.#.###.###.###.#.###.#.#########.# +#.#...............#...................#.#...#.......#.........#.....#...#...#.......#.....#...#...#.#.......#.#...#...#...#.#...#...#.......# +#.#.###.###.#.###.###.#.###.#.#.#####.#.#####.#######.#.#####.#.#####.#####.###.#.###########.#.###.#.#######.#.###.###.#.#.#.#.###.###.###.# +#.#...#.#...#...#.....#.....#.#...#.#.#...#...#.......#.#...#.#.#.....#...#.#...........#...#.#.#.#...#.....................#.#...#...#...#.# +#.#####.#.#################.#.###.#.#.###.#.#####.#####.#.#.#.#.#.#####.#.#.#.#.#.#####.#.#.#.#.#.#.###.###.#.#.#######.###.#.###.###.###.#.# +#.......#.................#.#...#...#.#.#.#...#...#.....#.#...#.#.#.....#...#...#...#...#.#.#.#.#.......#...#.#.#.....#.#...#.#.....#...#.#.# +#.#############.###.#######.###.###.#.#.#.###.#.#####.#.#.###.#.#.#.#####.#.###.#.###.###.#.###.###########.#.#.#.###.#.#.###.#.#######.#.#.# +#.#.........#.#.#...#.......#.#...#.#...#...#.#.#.....#...#.....#.#.#.....#.....#...#.....#...#.#.............................#.....#...#.#.# +#.#######.#.#.#.#####.#######.###.#####.###.#.#.#.#####.#######.#.#.#######.#######.#####.###.#.#.#.#.###.#######.#.###.#.#.#.#####.#.###.#.# +#S........#...............................#.....#...............#.#.........................#.....#...#...........#.......#.......#.......#.# +############################################################################################################################################# diff --git a/day-16/main.c b/day-16/main.c new file mode 100644 index 0000000..887a2e7 --- /dev/null +++ b/day-16/main.c @@ -0,0 +1,172 @@ +#include "aoc.h" +#include "limits.h" + +typedef struct { + i32 x, y; +} Vec2i; + +typedef enum { + Right, + Down, + Left, + Up, +} Orientation; + +static inline Orientation +turn(Orientation orientation, i32 delta) { + return (orientation + delta) % 4; +} + +static const Vec2i OFFSET[] = { + [Right] = { .x = 1, .y = 0 }, + [Down] = { .x = 0, .y = 1 }, + [Left] = { .x = -1, .y = 0 }, + [Up] = { .x = 0, .y = -1 }, +}; + +typedef struct { + i32 x, y; + Orientation orientation; +} Tile; + +typedef struct TileQueue { + Tile *tiles; + isize len; + isize read, write; +} TileQueue; + +static inline bool +tile_queue_empty(TileQueue *queue) { + return queue->read == queue->write; +} + +static Tile +tile_queue_pop(TileQueue *queue) { + ASSERT(!tile_queue_empty(queue)); + Tile result = queue->tiles[queue->read]; + queue->read = (queue->read + 1) % queue->len; + return result; +} + +static void +tile_queue_push(TileQueue *queue, i32 x, i32 y, Orientation orientation) { + isize next = (queue->write + 1) % queue->len; + ASSERT(next != queue->read); + queue->tiles[queue->write] = (Tile) { .x = x, .y = y, .orientation = orientation }; + queue->write = next; +} + +typedef struct { + i32 distance; + DYNAMIC_ARRAY(Tile) predecessors; +} Cell; + +static void +solve(Arena *arena, Grid *grid) { + i32 start_x = -1, start_y = -1; + i32 end_x = -1, end_y = -1; + for (i32 y = 0; y < grid->height; y++) { + for (i32 x = 0; x < grid->width; x++) { + if (grid->grid[y * grid->width + x] == 'E') { + end_x = x; + end_y = y; + } + else if (grid->grid[y * grid->width + x] == 'S') { + start_x = x; + start_y = y; + } + } + } + ASSERT(start_x != -1 && start_y != -1); + ASSERT(end_x != -1 && end_y != -1); + + Cell *cells = ARENA_ALLOC_ARRAY(arena, Cell, 4 * grid->width * grid->height); + for (isize i = 0; i < 4 * grid->width * grid->height; i++) { + cells[i].distance = INT_MAX; + } + // `cells` is a 3d array indexed as cells[4 * (y * width + x) + orientation] +#define CELL(x, y, o) cells[4 * ((y) * grid->width + (x)) + (o)] +#define DISTANCE(x, y, o) CELL(x, y, o).distance + + Orientation start_orientation = Right; + DISTANCE(start_x, start_y, start_orientation) = 0; + isize queue_size = 2048; + TileQueue queue = { + .tiles = ARENA_ALLOC_ARRAY(arena, Tile, queue_size), + .len = queue_size, + }; + tile_queue_push(&queue, start_x, start_y, start_orientation); + + while (!tile_queue_empty(&queue)) { + // walk straight + Tile current = tile_queue_pop(&queue); + i32 x = current.x; + i32 y = current.y; + Orientation orientation = current.orientation; + i32 dist = DISTANCE(current.x, current.y, current.orientation); + if (grid->grid[y * grid->width + x] == '#') { + continue; + } + i32 nx = current.x + OFFSET[current.orientation].x; + i32 ny = current.y + OFFSET[current.orientation].y; +#define TRY(x_, y_, o_, delta) do { \ + i32 candidate = DISTANCE(x_, y_, o_); \ + if (dist + delta <= candidate) { \ + DISTANCE(x_, y_, o_) = dist + delta; \ + Cell *cell = &CELL(x_, y_, o_); \ + if (dist + delta < candidate) { \ + tile_queue_push(&queue, x_, y_, o_); \ + cell->predecessors.len = 0; \ + } \ + *push(&cell->predecessors, arena) = (Tile) { .x = x, .y = y, .orientation = orientation }; \ + } \ +} while (0) + TRY(nx, ny, orientation, 1); + // turn 90deg cw + TRY(x, y, turn(orientation, 1), 1000); + // turn 180deg cw + TRY(x, y, turn(orientation, 2), 2000); + // turn 90deg ccw + TRY(x, y, turn(orientation, 3), 1000); +#undef TRY + } + + i32 part_1 = MIN4(DISTANCE(end_x, end_y, Right), DISTANCE(end_x, end_y, Down), DISTANCE(end_x, end_y, Left), DISTANCE(end_x, end_y, Up)); + + // Reconstruct best path + u8 *best_path = ARENA_ALLOC_ARRAY(arena, u8, grid->width * grid->height); + queue.write = 0; + queue.read = 0; + tile_queue_push(&queue, end_x, end_y, Right); + tile_queue_push(&queue, end_x, end_y, Down); + tile_queue_push(&queue, end_x, end_y, Left); + tile_queue_push(&queue, end_x, end_y, Up); + while (!tile_queue_empty(&queue)) { + Tile tile = tile_queue_pop(&queue); + best_path[tile.y * grid->width + tile.x] = 1; + Cell *cell = &CELL(tile.x, tile.y, tile.orientation); + for (isize i = 0; i < cell->predecessors.len; i++) { + Tile pred = cell->predecessors.data[i]; + tile_queue_push(&queue, pred.x, pred.y, pred.orientation); + } + } + + i32 part_2 = 0; + for (i32 y = 0; y < grid->height; y++) { + for (i32 x = 0; x < grid->width; x++) { + part_2 += (i32) best_path[y * grid->width + x]; + } + } + + printf("%d\n", part_1); + printf("%d\n", part_2); +#undef DISTANCE +#undef CELL +} + +int main(int argc, char **argv) { + Arena *arena = make_arena(Megabytes(16)); + Grid input = parse_grid(read_file(arena, argv[1]), arena); + + solve(arena, &input); +} diff --git a/day-16/test.txt b/day-16/test.txt new file mode 100644 index 0000000..2c21676 --- /dev/null +++ b/day-16/test.txt @@ -0,0 +1,15 @@ +############### +#.......#....E# +#.#.###.#.###.# +#.....#.#...#.# +#.###.#####.#.# +#.#.#.......#.# +#.#.#####.###.# +#...........#.# +###.#.#####.#.# +#...#.....#.#.# +#.#.#.###.#.#.# +#.....#...#.#.# +#.###.#.#.#.#.# +#S..#.....#...# +############### diff --git a/day-16/test2.txt b/day-16/test2.txt new file mode 100644 index 0000000..acb3491 --- /dev/null +++ b/day-16/test2.txt @@ -0,0 +1,4 @@ +########## +#S...#E..# +#........# +##########