Benjamin Kraft 9 months ago
parent 2508d4cd51
commit 3223948f51
  1. 120
      src/days/05/Day05.cpp
  2. 22
      src/days/05/Day05.h

@ -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();
auto seeds = parseSeeds();
auto maps = parseMaps();
uint64 min = UINT64_MAX;
for (size_t i = 0; i < seeds.size(); i += 2){
vector<Range> resultRanges {Range(seeds[i], seeds[i] + seeds[i + 1] - 1)};
for (const Map &map : maps){
vector<Range> 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<uint64> Day05::parseSeeds() const {
vector<uint64> 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::Map, 7> Day05::parseMaps() const {
std::array<Map, 7> 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<string> 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::Range> Day05::Map::get(Day05::Range src) const {
vector<Range> 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;
}

@ -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<Mapping> mappings;
uint64 get(uint64 src) const;
vector<Range> get(Range src) const;
};
protected:
Result Task1() override;
Result Task2() override;
vector<uint64> parseSeeds() const;
std::array<Map, 7> parseMaps() const;
};
Loading…
Cancel
Save