From b1efda9c7d843ce315c6646bd28855200c1e8a8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20M=C3=A5rdbrink?= Date: Mon, 9 Dec 2024 18:14:31 +0100 Subject: [PATCH] Day 9 --- d09/main.cxx | 112 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 6 deletions(-) diff --git a/d09/main.cxx b/d09/main.cxx index 3dff4c0..5c37362 100644 --- a/d09/main.cxx +++ b/d09/main.cxx @@ -1,15 +1,115 @@ #include -#include +#include +#include +#include +#include +#include + using std::cout, std::endl; +namespace views = std::ranges::views; -int main() { - std::ifstream file{"../d9/input.txt"}; - std::string line; +constexpr const char content[] = { + #embed "input.txt" +}; - while (std::getline(file, line)) { - +void fill_free_disk(std::vector>& disk) { + for(auto i{0}; i < disk.size(); i++) { + if(!disk[i].has_value()) { + for(auto j{disk.size() - 1}; j > i; j--) { + if(disk[j].has_value() && j > i) { + disk[i] = disk[j]; + disk[j] = std::nullopt; + break; + } + } + } + } +} + +long part_1() { + std::vector> disk = {}; + + int id_counter{1}; + for(int i = 0; i < sizeof(content); i++) { + std::optional id = i % 2 == 0 ? std::make_optional(i/2) : std::nullopt; + for(int j = 0; j < content[i] - '0'; j++) { + disk.push_back({id}); + } } + fill_free_disk(disk); + + long checksum{0}; + for(int i{0}; i < disk.size(); i++) { + if(disk[i].has_value()) { + checksum += i * disk[i].value(); + } + } + + return checksum; +} + +struct Partition { + std::optional id; + int start_index; + int size; + + bool operator==(const Partition& other) const { + return id == other.id && start_index == other.start_index; + } +}; +long part_2() { + std::vector partitions = {}; + + for(int i = 0; i < sizeof(content)-1; i++) { + std::optional id = i % 2 == 0 ? std::make_optional(i/2) : std::nullopt; + partitions.push_back({id, i, content[i] - '0'}); + } + + for(auto& free_space : partitions) { + if(!free_space.id.has_value()) { + for(auto& file : partitions | views::reverse) { + if(file.id.has_value() && file.size <= free_space.size && file.start_index > free_space.start_index) { + int space_left = free_space.size - file.size; + Partition move_file = file; + move_file.start_index = free_space.start_index; + file.id = std::nullopt; + + if(space_left == 0) { + partitions.erase(std::find(partitions.begin(), partitions.end(), free_space)); + } else { + free_space.size = space_left; + free_space.start_index += file.size; + } + + partitions.insert(std::find(partitions.begin(), partitions.end(), free_space), move_file); + break; + } + } + } + } + + int counter{0}; + long checksum{0}; + for(auto& partition : partitions) { + for(auto _ : views::iota(0, partition.size)) { + if(partition.id.has_value()) { + checksum += counter * partition.id.value(); + } + counter++; + } + } + return checksum; +} + +int main() { + std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); + auto p1_val = part_1(); + std::chrono::steady_clock::time_point middle = std::chrono::steady_clock::now(); + auto p2_val = part_2(); + std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); + cout << "Part 1: " << p1_val << " (" << std::chrono::duration_cast(middle - begin).count() << "µs)" << endl; + cout << "Part 2: " << p2_val << " (" << std::chrono::duration_cast(end - middle).count() << "µs)" << endl; return 0; }