parent
2508d4cd51
commit
3223948f51
2 changed files with 141 additions and 3 deletions
@ -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; |
||||
} |
||||
|
Loading…
Reference in new issue