From 2e39668605c5c26189732bdd9316d3a36eeb0fc4 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Wed, 18 Dec 2024 14:00:22 +0200 Subject: [PATCH] aoc2024: Implement day18 solution --- userspace/aoc2024/CMakeLists.txt | 1 + userspace/aoc2024/day18/CMakeLists.txt | 9 ++ userspace/aoc2024/day18/main.cpp | 125 +++++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 userspace/aoc2024/day18/CMakeLists.txt create mode 100644 userspace/aoc2024/day18/main.cpp diff --git a/userspace/aoc2024/CMakeLists.txt b/userspace/aoc2024/CMakeLists.txt index d5065881..e0329a37 100644 --- a/userspace/aoc2024/CMakeLists.txt +++ b/userspace/aoc2024/CMakeLists.txt @@ -16,6 +16,7 @@ set(AOC2024_PROJECTS day15 day16 day17 + day18 full ) diff --git a/userspace/aoc2024/day18/CMakeLists.txt b/userspace/aoc2024/day18/CMakeLists.txt new file mode 100644 index 00000000..4231ab64 --- /dev/null +++ b/userspace/aoc2024/day18/CMakeLists.txt @@ -0,0 +1,9 @@ +set(SOURCES + main.cpp +) + +add_executable(aoc2024_day18 ${SOURCES}) +banan_include_headers(aoc2024_day18 ban) +banan_link_library(aoc2024_day18 libc) + +install(TARGETS aoc2024_day18 OPTIONAL) diff --git a/userspace/aoc2024/day18/main.cpp b/userspace/aoc2024/day18/main.cpp new file mode 100644 index 00000000..5b174186 --- /dev/null +++ b/userspace/aoc2024/day18/main.cpp @@ -0,0 +1,125 @@ +#include +#include +#include + +#include +#include + +using i8 = int8_t; +using i16 = int16_t; +using i32 = int32_t; +using i64 = int64_t; +using isize = ssize_t; + +using u8 = uint8_t; +using u16 = uint16_t; +using u32 = uint32_t; +using u64 = uint64_t; +using usize = size_t; + +template +struct Vec2 +{ + T x, y; +}; + +template +static BAN::Optional steps_to_finnish(BAN::Array, H>& map) +{ + BAN::Vector> pending; + MUST(pending.push_back({ 0, 0 })); + + for (usize step = 0;; step++) + { + BAN::Vector> next; + for (auto pos : pending) + { + if (map[pos.y][pos.x]) + continue; + map[pos.y][pos.x] = true; + + if (pos.x == W - 1 && pos.y == H - 1) + return step; + + if (pos.y > 0 && !map[pos.y - 1][pos.x ]) MUST(next.push_back({ pos.x, pos.y - 1 })); + if (pos.x > 0 && !map[pos.y ][pos.x - 1]) MUST(next.push_back({ pos.x - 1, pos.y })); + if (pos.y < H - 1 && !map[pos.y + 1][pos.x ]) MUST(next.push_back({ pos.x, pos.y + 1 })); + if (pos.x < W - 1 && !map[pos.y ][pos.x + 1]) MUST(next.push_back({ pos.x + 1, pos.y })); + } + + if (next.empty()) + break; + pending = BAN::move(next); + } + + return {}; +} + +i64 part1(FILE* fp) +{ + BAN::Array, 71> map(false); + for (usize i = 0; i < 1024; i++) + { + usize x, y; + ASSERT(fscanf(fp, "%zu,%zu\n", &x, &y) == 2); + map[y][x] = true; + } + + return steps_to_finnish(map).value(); +} + +BAN::String part2(FILE* fp) +{ + BAN::Vector> bytes; + for (;;) + { + usize x, y; + if (fscanf(fp, "%zu,%zu\n", &x, &y) != 2) + break; + MUST(bytes.push_back({ x, y })); + } + + usize l = 0; + usize r = bytes.size() - 1; + + while (l <= r) + { + const usize mid = l + (r - l) / 2; + + BAN::Array, 71> map(false); + for (usize i = 0; i <= mid; i++) + map[bytes[i].y][bytes[i].x] = true; + + if (steps_to_finnish(map).has_value()) + l = mid + 1; + else if (l == mid) + return MUST(BAN::String::formatted("{},{}", bytes[mid].x, bytes[mid].y)); + else + r = mid; + } + + ASSERT_NOT_REACHED(); +} + +int main(int argc, char** argv) +{ + const char* file_path = "/usr/share/aoc2024/day18_input.txt"; + + if (argc >= 2) + file_path = argv[1]; + + FILE* fp = fopen(file_path, "r"); + if (fp == nullptr) + { + perror("fopen"); + return 1; + } + + printf("part1: %" PRId64 "\n", part1(fp)); + + fseek(fp, 0, SEEK_SET); + + printf("part2: %s\n", part2(fp).data()); + + fclose(fp); +}