This commit is contained in:
Eric Mertens 2022-11-19 10:30:09 -08:00
parent ed07924b0a
commit 1d583ed6e4
3 changed files with 158 additions and 2 deletions

71
2020/02.cpp Normal file
View File

@ -0,0 +1,71 @@
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <tuple>
#include <cstdio>
#include <cstdlib>
#include <doctest.h>
#include <aocpp/Startup.hpp>
namespace {
using Entry = std::tuple<std::size_t, std::size_t, char, std::string>;
auto Parse(std::string const& str) -> Entry
{
std::size_t lo, hi, n;
char letter;
auto res = std::sscanf(str.c_str(), "%zu-%zu %c: %zn", &lo, &hi, &letter, &n);
if (res != 3) { throw std::runtime_error{"bad input"}; }
return {lo, hi, letter, str.substr(n)};
}
auto Part1(Entry const& entry) -> bool {
auto const& [lo, hi, letter, text] = entry;
auto n = std::count(text.begin(), text.end(), letter);
return lo <= n && n <= hi;
}
auto Part2(Entry const& entry) -> bool
{
auto const& [lo, hi, letter, text] = entry;
return (text.at(lo-1) == letter) != (text.at(hi-1) == letter);
}
} // namespace
TEST_SUITE("documented examples") {
TEST_CASE("parser") {
REQUIRE(Parse("1-3 z: example") == Entry{1,3,'z',"example"});
}
TEST_CASE("part 1") {
REQUIRE( Part1(Parse("1-3 a: abcde")));
REQUIRE(!Part1(Parse("1-3 b: cdefg")));
REQUIRE( Part1(Parse("2-9 c: ccccccccc")));
}
TEST_CASE("part 2") {
REQUIRE( Part2(Parse("1-3 a: abcde")));
REQUIRE(!Part2(Parse("1-3 b: cdefg")));
REQUIRE(!Part2(Parse("2-9 c: ccccccccc")));
}
}
auto main(int argc, char** argv) -> int {
auto & in = aocpp::Startup(argc, argv);
std::uint64_t part1{}, part2{};
std::string line;
while (std::getline(in, line)) {
auto entry = Parse(line);
if (Part1(entry)) part1++;
if (Part2(entry)) part2++;
}
std::cout << "Part 1: " << part1 << std::endl;
std::cout << "Part 2: " << part2 << std::endl;
}

82
2020/03.cpp Normal file
View File

@ -0,0 +1,82 @@
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <sstream>
#include <tuple>
#include <cstdio>
#include <cstdlib>
#include <numeric>
#include <functional>
#include <doctest.h>
#include <aocpp/Startup.hpp>
#include <aocpp/Grid.hpp>
#include <aocpp/Coord.hpp>
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;
}

View File

@ -1,2 +1,5 @@
add_executable(2020_01 01.cpp) add_executable(2020_02 02.cpp)
target_link_libraries(2020_01 aocpp) target_link_libraries(2020_02 aocpp)
add_executable(2020_03 03.cpp)
target_link_libraries(2020_03 aocpp)