#include #include #include #include "days.hpp" #include "point.hpp" namespace { typedef aoc2019::Point point_t; using aoc2019::from_chars; std::vector read_moons(std::istream &input) { std::vector moons; point_t moon; while (aoc2019::read_line_numbers_and_garbage(input, moon.begin())) { moons.push_back(moon); } return moons; } void update_velocity(const point_t &a, point_t &va, const point_t &b, point_t &vb) { for (int i = 0; i < a.size(); ++i) { if (a[i] < b[i]) { va[i]++; vb[i]--; } else if (a[i] > b[i]) { va[i]--; vb[i]++; } } } void update_velocities(const std::vector &positions, std::vector &velocities) { for (int i = 0; i < positions.size(); ++i) { for (int j = i + 1; j < positions.size(); ++j) { update_velocity(positions[i], velocities[i], positions[j], velocities[j]); } } } void simulate_step(std::vector &moons, std::vector &velocities) { update_velocities(moons, velocities); for (int j = 0; j < moons.size(); ++j) { moons[j] += velocities[j]; } } } void aoc2019::day12_part1(std::istream &input, std::ostream &output) { auto moons = read_moons(input); std::vector velocities(moons.size()); for (int i = 0; i < 1000; ++i) { simulate_step(moons, velocities); } int energy = 0; for (int i = 0; i < moons.size(); ++i) { energy += moons[i].l1() * velocities[i].l1(); } output << energy << std::endl; } void aoc2019::day12_part2(std::istream &input, std::ostream &output) { const auto moons = read_moons(input); auto moons_mut = moons; std::vector velocities(moons.size()); std::array recurrence = {0, 0, 0}; std::uint64_t steps = 0; while (!std::all_of(recurrence.begin(), recurrence.end(), [](auto x) { return x > 0; })) { simulate_step(moons_mut, velocities); ++steps; for (int i = 0; i < 3; ++i) { if (!recurrence[i]) { bool back_again = std::all_of(velocities.begin(), velocities.end(), [i](const auto &x) { return !x[i]; }) && std::equal(moons_mut.begin(), moons_mut.end(), moons.begin(), [i](const auto &a, const auto &b) { return a[i] == b[i]; }); if (back_again) { recurrence[i] = steps; } } } } auto result = std::lcm(recurrence[0], std::lcm(recurrence[1], recurrence[2])); output << result << std::endl; }