From 3223948f511f76570c2820135bb47f29a831e9a2 Mon Sep 17 00:00:00 2001 From: Benjamin Kraft Date: Tue, 19 Dec 2023 00:57:46 +0100 Subject: [PATCH] Day 5 --- src/days/05/Day05.cpp | 122 ++++++++++++++++++++++++++++++++++++++++-- src/days/05/Day05.h | 22 ++++++++ 2 files changed, 141 insertions(+), 3 deletions(-) diff --git a/src/days/05/Day05.cpp b/src/days/05/Day05.cpp index 34bffac..eaca7c7 100644 --- a/src/days/05/Day05.cpp +++ b/src/days/05/Day05.cpp @@ -1,9 +1,125 @@ #include "Day05.h" Result Day05::Task1() { - return Day::Task1(); + auto seeds = parseSeeds(); + auto maps = parseMaps(); + + uint64 min = UINT64_MAX; + + for (uint64 seed : seeds){ + uint64 result = seed; + for (const Map &map : maps) + result = map.get(result); + min = std::min(min, result); + } + + return to_string(min); } Result Day05::Task2() { - return Day::Task2(); -} \ No newline at end of file + auto seeds = parseSeeds(); + auto maps = parseMaps(); + + uint64 min = UINT64_MAX; + + for (size_t i = 0; i < seeds.size(); i += 2){ + vector resultRanges {Range(seeds[i], seeds[i] + seeds[i + 1] - 1)}; + for (const Map &map : maps){ + vector newRanges; + for (const Range &range : resultRanges) { + auto add = map.get(range); + std::copy(add.begin(), add.end(), std::back_inserter(newRanges)); + } + resultRanges = newRanges; + } + for (const Range &range : resultRanges) + min = std::min(min, range.start); + } + + return to_string(min); +} + +vector Day05::parseSeeds() const { + vector seeds; + auto list = (input[0] + " ").substr(7); + size_t start = 0; + for (size_t i : findAll(list, " ")){ + seeds.push_back(std::stoul(list.substr(start, i - start))); + start = i; + } + + return seeds; +} + +std::array Day05::parseMaps() const { + std::array maps; + + size_t map = 0; + + for (size_t i = 3; i < input.size(); i++){ + string line = input[i]; + if (line.empty()){ + i++; + map++; + continue; + } + + vector values = split(line, ' '); + maps[map].mappings.insert(Mapping(std::stoul(values[0]), std::stoul(values[1]), std::stoul(values[2]))); + } + + return maps; +} + +uint64 Day05::Mapping::get(uint64 src) const { + return src - source + destination; +} + +Day05::Range Day05::Mapping::get(Day05::Range src) const { + if (containsKey(src.start) && containsKey(src.end)) + return Range(get(src.start), get(src.end)); + if (containsKey(src.start)) + return Range(get(src.start), get(source + range - 1)); + if (containsKey(src.end)) + return Range(get(source), get(src.end)); + return Range(get(source), get(source + range - 1)); +} + +bool Day05::Mapping::touchesRange(Day05::Range src) const { + return !(src.end < source || src.start > source + range - 1); +} + + +uint64 Day05::Map::get(uint64 src) const { + for (const Mapping &mapping : mappings) + if (mapping.containsKey(src)) + return mapping.get(src); + return src; +} + +vector Day05::Map::get(Day05::Range src) const { + vector ranges; + + uint64 minSource = mappings.begin()->source; + uint64 maxSource = (--mappings.end())->source + (--mappings.end())->range - 1; + if (src.end < minSource || src.start > maxSource) + return {src}; + if (src.start < minSource) + ranges.emplace_back(src.start, minSource - 1); + if (src.end > maxSource) + ranges.emplace_back(maxSource + 1, src.end); + + for (const Mapping &mapping : mappings) + if (mapping.touchesRange(src)) + ranges.emplace_back(mapping.get(src)); + + return ranges; +} + +bool Day05::Mapping::containsKey(uint64 src) const { + return src >= source && src < source + range; +} + +bool Day05::Mapping::operator<(const Day05::Mapping &other) const { + return source < other.source; +} diff --git a/src/days/05/Day05.h b/src/days/05/Day05.h index 128dacd..34b7036 100644 --- a/src/days/05/Day05.h +++ b/src/days/05/Day05.h @@ -3,8 +3,30 @@ #include "../../Day.h" class Day05 : public Day { + struct Range { + uint64 start; + uint64 end; + }; + struct Mapping { + uint64 destination; + uint64 source; + uint64 range; + bool containsKey(uint64 src) const; + uint64 get(uint64 src) const; + bool touchesRange(Range src) const; + Range get(Range src) const; + bool operator <(const Mapping &other) const; + }; + struct Map { + set mappings; + uint64 get(uint64 src) const; + vector get(Range src) const; + }; protected: Result Task1() override; Result Task2() override; + + vector parseSeeds() const; + std::array parseMaps() const; }; \ No newline at end of file