#include <algorithm>
#include <cstdint>
#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
#include <map>
#include <tuple>
#include <string>
#include <numeric>

#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

auto Main(std::istream & in, std::ostream & out) -> void
{
  std::string line;
  std::getline(in, line);
  auto wire0 = BuildLine(line);
  std::getline(in, line);
  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);
    }
  }

  out << "Part 1: " << part1 << std::endl;
  out << "Part 2: " << part2 << std::endl;
}