2022-11-07 17:19:17 -08:00
|
|
|
#include <algorithm>
|
|
|
|
#include <cstdint>
|
|
|
|
#include <iostream>
|
|
|
|
#include <fstream>
|
|
|
|
#include <iterator>
|
|
|
|
#include <vector>
|
|
|
|
#include <map>
|
|
|
|
#include <tuple>
|
|
|
|
#include <string>
|
2022-11-11 19:21:39 -08:00
|
|
|
#include <numeric>
|
2022-11-07 17:19:17 -08:00
|
|
|
|
|
|
|
#include <aocpp/Coord.hpp>
|
|
|
|
#include <aocpp/Startup.hpp>
|
|
|
|
using namespace aocpp;
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
auto BuildLine(std::string instructions) -> std::vector<Coord>
|
|
|
|
{
|
|
|
|
Coord here {};
|
|
|
|
std::vector<Coord> 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<Coord, Entry> & m,
|
|
|
|
bool Entry::* which,
|
|
|
|
std::vector<Coord> 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
|
|
|
|
|
2023-01-31 08:58:42 -08:00
|
|
|
auto Main(std::istream & in) -> void
|
|
|
|
{
|
2022-11-07 17:19:17 -08:00
|
|
|
std::string line;
|
2022-11-07 21:00:14 -08:00
|
|
|
std::getline(in, line);
|
2022-11-07 17:19:17 -08:00
|
|
|
auto wire0 = BuildLine(line);
|
2022-11-07 21:00:14 -08:00
|
|
|
std::getline(in, line);
|
2022-11-07 17:19:17 -08:00
|
|
|
auto wire1 = BuildLine(line);
|
|
|
|
|
|
|
|
std::map<Coord, Entry> counts;
|
|
|
|
Record(counts, &Entry::w0, wire0);
|
|
|
|
Record(counts, &Entry::w1, wire1);
|
|
|
|
|
|
|
|
std::int64_t part1 = std::numeric_limits<std::int64_t>::max();
|
|
|
|
std::int64_t part2 = std::numeric_limits<std::int64_t>::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;
|
|
|
|
}
|