This commit is contained in:
Eric Mertens 2022-11-13 20:14:46 -08:00
parent b6e3631916
commit bb6d1eeb90

View File

@ -1,9 +1,12 @@
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <utility> #include <map>
#include <numeric> #include <numeric>
#include <set> #include <set>
#include <map> #include <sstream>
#include <utility>
#include <doctest.h>
#include <aocpp/Startup.hpp> #include <aocpp/Startup.hpp>
#include <aocpp/Coord.hpp> #include <aocpp/Coord.hpp>
@ -87,7 +90,7 @@ auto Part1(Grid const& grid) {
return std::make_pair(best, base); return std::make_pair(best, base);
} }
auto Part2(Grid const& grid, Coord base) { auto Part2(Grid const& grid, Coord base, std::size_t n) {
std::map<Rational<std::int64_t>, std::vector<Coord>> targets; std::map<Rational<std::int64_t>, std::vector<Coord>> targets;
// arrange all the other asteroids by their angle relative to the base // arrange all the other asteroids by their angle relative to the base
@ -107,7 +110,7 @@ auto Part2(Grid const& grid, Coord base) {
// Remove 199 asteroids from the asteroid list // Remove 199 asteroids from the asteroid list
auto cursor = targets.begin(); auto cursor = targets.begin();
for (std::size_t n = 199; n > 0; n--) { for (; n > 1; n--) {
if (targets.empty()) { throw std::runtime_error{"no solution to part 2"}; } if (targets.empty()) { throw std::runtime_error{"no solution to part 2"}; }
cursor->second.pop_back(); cursor->second.pop_back();
@ -129,9 +132,85 @@ auto Part2(Grid const& grid, Coord base) {
} // namespace } // namespace
TEST_SUITE("documented examples") {
char const* bigexample =
".#..##.###...#######\n"
"##.############..##.\n"
".#.######.########.#\n"
".###.#######.####.#.\n"
"#####.##.#.##.###.##\n"
"..#####..#.#########\n"
"####################\n"
"#.####....###.#.#.##\n"
"##.#################\n"
"#####.##.###..####..\n"
"..######..##.#######\n"
"####.##.####...##..#\n"
".#####..#.######.###\n"
"##...#.##########...\n"
"#.##########.#######\n"
".####.#.###.###.#.##\n"
"....##.##.###..#####\n"
".#.#.###########.###\n"
"#.#.#.#####.####.###\n"
"###.##.####.##.#..##\n";
TEST_CASE("part 1") {
auto test = [](Coord base, std::size_t count, std::string text) {
std::istringstream in {std::move(text)};
auto [count_, base_] = Part1(Grid::Parse(in));
REQUIRE(count_ == count);
REQUIRE(base_ == base);
};
test({3,4}, 8,
".#..#\n"
".....\n"
"#####\n"
"....#\n"
"...##\n");
test({1,2}, 35,
"#.#...#.#.\n"
".###....#.\n"
".#....#...\n"
"##.#.#.#.#\n"
"....#.#.#.\n"
".##..###.#\n"
"..#...##..\n"
"..##....##\n"
"......#...\n"
".####.###.\n");
test({6,3}, 41,
".#..#..###\n"
"####.###.#\n"
"....###.#.\n"
"..###.##.#\n"
"##.##.#.#.\n"
"....###..#\n"
"..#.#..#.#\n"
"#..#.#.###\n"
".##...##.#\n"
".....#.#..\n");
test({11,13}, 210, bigexample);
}
TEST_CASE("part 2") {
auto test = [](std::size_t answer, Coord base, std::size_t nth, std::string text) {
std::istringstream in {std::move(text)};
REQUIRE(answer == Part2(Grid::Parse(in), base, nth));
};
test(1403, {8,3}, 36,
".#....#####...#..\n"
"##...##.#####..##\n"
"##...#...#.#####.\n"
"..#.....X...###..\n"
"..#.#.....#....##\n");
test(802, {11,13}, 200, bigexample);
}
}
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto grid = Grid::Parse(Startup(argc, argv)); auto grid = Grid::Parse(Startup(argc, argv));
auto [part1, base] = Part1(grid); auto [part1, base] = Part1(grid);
std::cout << "Part 1: " << part1 << std::endl; std::cout << "Part 1: " << part1 << std::endl;
std::cout << "Part 2: " << Part2(grid, base) << std::endl; std::cout << "Part 2: " << Part2(grid, base, 200) << std::endl;
} }