From b18f6ae092e974ab77b525c47308f147d385ceda Mon Sep 17 00:00:00 2001 From: Eric Mertens Date: Sat, 28 Dec 2024 13:17:46 -0600 Subject: [PATCH] 2024-07 --- 2024/07.cpp | 63 ++++++++++++++++++++++++++ 2024/22.cpp | 83 +++++++++++++++++++++++++++++++++++ 2024/CMakeLists.txt | 5 +++ CMakeLists.txt | 1 + lib/include/aocpp/Parsing.hpp | 15 +++++++ 5 files changed, 167 insertions(+) create mode 100644 2024/07.cpp create mode 100644 2024/22.cpp create mode 100644 2024/CMakeLists.txt diff --git a/2024/07.cpp b/2024/07.cpp new file mode 100644 index 0000000..dfdd22e --- /dev/null +++ b/2024/07.cpp @@ -0,0 +1,63 @@ +#include +#include + +#include +#include + +#include +#include + +namespace qi = boost::spirit::qi; + +namespace { + +auto +suffixed(std::uint64_t x, std::uint64_t y) -> std::optional +{ + while (x > 0) { + if (y == 0) { return x; } + if (x % 10 != y % 10) { return {}; } + x /= 10; + y /= 10; + } + return {}; +} + +auto +check(bool part2, std::uint64_t target, std::vector const& numbers) -> bool +{ + std::stack> work; + work.push({numbers.size() - 1, target}); + + while (!work.empty()){ + auto [i, t] = work.top(); + work.pop(); + auto x = numbers[i]; + if (i == 0) { + if (x == t) return true; + } else { + if (x < t) { work.push({i-1, t-x}); } + if (t % x == 0) { work.push({i-1, t/x}); } + if (part2) { if (auto u = suffixed(t,x)) { work.push({i-1, *u}); } } + } + } + + return false; +} + +} // namespace + +auto Main(std::istream & in, std::ostream & out) -> void +{ + std::vector>> input; + aocpp::ParseSimple(in, *(qi::ulong_long >> ":" >> *(" " >> qi::ulong_long) >> "\n"), input); + + std::uint64_t p1{}, p2{}; + for (auto && [x, xs] : input) { + if (check(false, x, xs)) p1 += x; + if (check(true, x, xs)) p2 += x; + } + + out << "Part 1: " << p1 << "\n" + << "Part 2: " << p2 << "\n"; +} diff --git a/2024/22.cpp b/2024/22.cpp new file mode 100644 index 0000000..d75d7f6 --- /dev/null +++ b/2024/22.cpp @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace { + +using Input = std::vector; + +auto Parse(std::istream & in) -> Input +{ + Input results {}; + std::for_each( + std::istream_iterator{in}, + std::istream_iterator{}, + [&](std::string line) { + results.push_back(std::stoul(line)); + } + ); + return results; +} + +auto Next(std::uint32_t x) -> std::uint32_t +{ + x = (x ^ (x << 6)) & 0xffffff; + x = (x ^ (x >> 5)) & 0xffffff; + x = (x ^ (x << 11)) & 0xffffff; + return x; +} + +auto Solve(Input entries) -> std::pair +{ + std::vector patterns(std::size(entries)); + std::vector counts(19*19*19*19); + std::vector seen(std::size(entries)*19*19*19*19); + + for (std::size_t i = 0; i < 3; ++i) { + for (std::size_t j = 0; j < entries.size(); ++j) { + auto const x = entries[j]; + auto const y = Next(x); + entries[j] = y; + patterns[j] = patterns[j] * 19 + y%10 + 9 - x%10; + } + } + + for (std::size_t i = 3; i < 2'000; ++i) { + for (std::size_t j = 0; j < entries.size(); ++j) { + auto const x = entries[j]; + auto const y = Next(x); + entries[j] = y; + auto const p = patterns[j] % (19 * 19 * 19) * 19 + y%10 + 9 - x%10; + patterns[j] = p; + if (!seen[j * 19 * 19 * 19 * 19 + p]) { + seen[j * 19 * 19 * 19 * 19 + p] = true; + counts[p] += y%10; + } + } + } + + auto const p1 = std::accumulate(begin(entries), end(entries), std::uint64_t{0}); + auto const p2 = *std::max_element(begin(counts), end(counts)); + return {p1, p2}; +} + + +} // namespace + +auto Main(std::istream & in, std::ostream & out) -> void +{ + auto entries = Parse(in); + auto const [p1, p2] = Solve(std::move(entries)); + out << "Part 1: " << p1 << "\n" + << "Part 2: " << p2 << "\n"; +} diff --git a/2024/CMakeLists.txt b/2024/CMakeLists.txt new file mode 100644 index 0000000..943266a --- /dev/null +++ b/2024/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(2024_07 07.cpp) +target_link_libraries(2024_07 aocpp Boost::headers) + +add_executable(2024_22 22.cpp) +target_link_libraries(2024_22 aocpp) diff --git a/CMakeLists.txt b/CMakeLists.txt index ecf9198..a8aacae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,3 +35,4 @@ add_subdirectory(2020) add_subdirectory(2021) add_subdirectory(2022) add_subdirectory(2023) +add_subdirectory(2024) diff --git a/lib/include/aocpp/Parsing.hpp b/lib/include/aocpp/Parsing.hpp index 1dd61ac..a1c9f31 100644 --- a/lib/include/aocpp/Parsing.hpp +++ b/lib/include/aocpp/Parsing.hpp @@ -7,6 +7,7 @@ #include #include +#include namespace aocpp { @@ -46,6 +47,20 @@ auto ParseGrammar_(G const& grammar, std::istream & in) -> typename G::start_typ return result; } +template +auto ParseSimple(std::istream& in, P p, R & result) -> void +{ + namespace qi = boost::spirit::qi; + auto const content = std::string{std::istreambuf_iterator{in}, {}}; + qi::rule r { std::move(p) }; + auto it = content.begin(); + auto const end = content.end(); + bool success = qi::parse(it, end, r, result); + if (!success || it != end) { + throw std::runtime_error("Parsing failed or input was not fully consumed."); + } +} + } #endif