diff --git a/2015/01.cpp b/2015/01.cpp new file mode 100644 index 0000000..ae2cf05 --- /dev/null +++ b/2015/01.cpp @@ -0,0 +1,35 @@ +#include + +#include +#include + +auto Main(std::istream & in, std::ostream & out) -> void +{ + std::string line; + std::getline(in, line); + + std::int64_t part1 = 0; + std::size_t part2 = 0; + + for (std::size_t i = 0; i < line.size(); ++i) + { + switch (line[i]) { + case '(': part1++; break; + case ')': part1--; break; + default: throw std::runtime_error{"Invalid input character"}; + } + + if (part2 == 0 && part1 == -1) + { + part2 = i + 1; + } + } + + if (part2 == 0) + { + throw std::runtime_error{"No part 2 solution"}; + } + + out << "Part 1: " << part1 << std::endl; + out << "Part 2: " << part2 << std::endl; +} diff --git a/2015/02.cpp b/2015/02.cpp new file mode 100644 index 0000000..a929e88 --- /dev/null +++ b/2015/02.cpp @@ -0,0 +1,71 @@ +#include + +#include + +#include + +#include +#include +#include +#include + +struct Box +{ + std::int64_t x; + std::int64_t y; + std::int64_t z; +}; + +auto Part1(Box const& box) -> std::int64_t +{ + std::array sides {box.x * box.y, box.x * box.z, box.y * box.z}; + std::partial_sort(begin(sides), begin(sides)+1, end(sides)); + return 2 * std::reduce(begin(sides), end(sides)) + sides[0]; +} + +auto Part2(Box const& box) -> std::int64_t +{ + std::array dims {box.x, box.y, box.z}; + std::sort(begin(dims), end(dims)); + return 2 * (dims[0] + dims[1]) + std::reduce(begin(dims), end(dims), 1, std::multiplies<>()); +} + +TEST_SUITE("documented examples") { + +TEST_CASE("part 1") { + REQUIRE(Part1({2,3,4}) == 58); + REQUIRE(Part1({1,1,10}) == 43); +} + +TEST_CASE("part 2") { + REQUIRE(Part2({2,3,4}) == 34); + REQUIRE(Part2({1,1,10}) == 14); +} + +} + +auto Main(std::istream & in, std::ostream & out) -> void +{ + std::int64_t part1 = 0; + std::int64_t part2 = 0; + + std::string line; + while (std::getline(in, line)) { + namespace qi = boost::spirit::qi; + using p = qi::int_parser; + auto b = begin(line); // updated on successful parse + auto const e = end(line); + + Box box; + if (not qi::parse(b, e, p{} >> 'x' >> p{} >> 'x' >> p{}, box.x, box.y, box.z) || b != e) + { + throw std::runtime_error{"Parse error"}; + } + + part1 += Part1(box); + part2 += Part2(box); + } + + std::cout << "Part1: " << part1 << std::endl; + std::cout << "Part2: " << part2 << std::endl; +} diff --git a/2015/CMakeLists.txt b/2015/CMakeLists.txt new file mode 100644 index 0000000..7275f05 --- /dev/null +++ b/2015/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(2015_01 01.cpp) +target_link_libraries(2015_01 aocpp) + +add_executable(2015_02 02.cpp) +target_link_libraries(2015_02 aocpp) diff --git a/CMakeLists.txt b/CMakeLists.txt index 94e5b4e..93bd855 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,7 @@ add_subdirectory(dlx) add_subdirectory(knothash) add_subdirectory(zmod) add_subdirectory(intcode) +add_subdirectory(2015) add_subdirectory(2016) add_subdirectory(2017) add_subdirectory(2018) diff --git a/lib/include/aocpp/Counter.hpp b/lib/include/aocpp/Counter.hpp index 0e3e87d..269eaf8 100644 --- a/lib/include/aocpp/Counter.hpp +++ b/lib/include/aocpp/Counter.hpp @@ -8,7 +8,7 @@ struct Counter { using difference_type = std::ptrdiff_t; - struct EmptyRef { + struct NoOpReference { template auto operator=(T&&) const -> void {} }; @@ -31,14 +31,14 @@ struct Counter return n++; } - auto operator*() const -> EmptyRef + auto operator*() const -> NoOpReference { return {}; } auto operator-(Counter rhs) const -> difference_type { - return static_cast(n) - static_cast(rhs); + return static_cast(n) - static_cast(rhs.n); } operator std::size_t() const diff --git a/lib/include/aocpp/Parsing.hpp b/lib/include/aocpp/Parsing.hpp index 223665a..1dd61ac 100644 --- a/lib/include/aocpp/Parsing.hpp +++ b/lib/include/aocpp/Parsing.hpp @@ -48,4 +48,4 @@ auto ParseGrammar_(G const& grammar, std::istream & in) -> typename G::start_typ } -#endif \ No newline at end of file +#endif