#include #include #include #include #include #include #include #include #include #include #include #include #include using aocpp::Startup; using aocpp::Coord; using aocpp::Grid; namespace { auto Ski(Grid const& grid, Coord step) -> std::size_t { std::size_t const w = grid.rows[0].size(); std::size_t trees {0}; Coord here {0,0}; while(here.y < grid.rows.size()) { if (grid[here] == '#') trees++; here += step; while (here.x >= w) { here.x -= w; } } return trees; } auto Part1(Grid const& grid) { return Ski(grid, {3,1}); } auto Part2(Grid const& grid) { Coord const slopes[] = {{1,1}, {3,1}, {5,1}, {7,1}, {1,2}}; return std::transform_reduce( std::begin(slopes), std::end(slopes), 1ULL, std::multiplies(), [&](Coord slope) { return Ski(grid, slope); }); } } // namespace TEST_SUITE("documented examples") { std::istringstream in { "..##.......\n" "#...#...#..\n" ".#....#..#.\n" "..#.#...#.#\n" ".#...##..#.\n" "..#.##.....\n" ".#.#.#....#\n" ".#........#\n" "#.##...#...\n" "#...##....#\n" ".#..#...#.#\n" }; auto grid = Grid::Parse(in); TEST_CASE("part 1") { REQUIRE(Part1(grid) == 7); } TEST_CASE("part 2") { REQUIRE(Part2(grid) == 336); } } auto main(int argc, char** argv) -> int { auto grid = Grid::Parse(*Startup(argc, argv)); std::cout << "Part 1: " << Part1(grid) << std::endl; std::cout << "Part 2: " << Part2(grid) << std::endl; }