#include #include #include #include #include #include #include #include #include #include #include #include using namespace aocpp; namespace { auto BuildLine(std::string instructions) -> std::vector { Coord here {}; std::vector wire; auto it = std::begin(instructions); auto end = std::end(instructions); while (it != end) { auto start = it; it = std::find(it, end, ','); if (start == it) { throw std::runtime_error{"null command"}; } Coord (*step)(Coord); switch (*start++) { case 'U': step = Up; break; case 'D': step = Down; break; case 'L': step = Left; break; case 'R': step = Right; break; default: throw std::runtime_error{"bad command letter"}; } auto n = std::stol(std::string{start, it}); for (int i = 0; i < n; i++) { here = step(here); wire.push_back(here); } // skip over comma if (it != end) it++; } return wire; } struct Entry { bool w0, w1; std::int64_t part2; }; auto Record ( std::map & m, bool Entry::* which, std::vector const& wire ) -> void { for (std::size_t i = 0; i < wire.size(); i++) { auto & entry = m[wire[i]]; if (!(entry.*which)) { entry.*which = true; entry.part2 += i+1; } } } } // namespace auto main(int argc, char** argv) -> int { auto in_ptr = aocpp::Startup(argc, argv); auto & in = *in_ptr; std::string line; std::getline(in, line); auto wire0 = BuildLine(line); std::getline(in, line); auto wire1 = BuildLine(line); std::map counts; Record(counts, &Entry::w0, wire0); Record(counts, &Entry::w1, wire1); std::int64_t part1 = std::numeric_limits::max(); std::int64_t part2 = std::numeric_limits::max(); for (auto & [k,v] : counts) { if (v.w0 && v.w1) { part1 = std::min(part1, Norm1(k)); part2 = std::min(part2, v.part2); } } std::cout << "Part 1: " << part1 << std::endl; std::cout << "Part 2: " << part2 << std::endl; }