This commit is contained in:
Eric Mertens 2024-12-28 13:17:46 -06:00
parent d6fc0396cb
commit b18f6ae092
5 changed files with 167 additions and 0 deletions

63
2024/07.cpp Normal file
View File

@ -0,0 +1,63 @@
#include <aocpp/Parsing.hpp>
#include <aocpp/Startup.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/spirit/include/qi.hpp>
#include <optional>
#include <stack>
namespace qi = boost::spirit::qi;
namespace {
auto
suffixed(std::uint64_t x, std::uint64_t y) -> std::optional<std::uint64_t>
{
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<std::uint64_t> const& numbers) -> bool
{
std::stack<boost::tuple<std::size_t, std::uint64_t>> 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<boost::tuple<std::uint64_t, std::vector<std::uint64_t>>> 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";
}

83
2024/22.cpp Normal file
View File

@ -0,0 +1,83 @@
#include <algorithm>
#include <cctype>
#include <cstdint>
#include <iostream>
#include <string_view>
#include <string>
#include <tuple>
#include <tuple>
#include <vector>
#include <numeric>
#include <functional>
#include <aocpp/Startup.hpp>
namespace {
using Input = std::vector<std::uint32_t>;
auto Parse(std::istream & in) -> Input
{
Input results {};
std::for_each(
std::istream_iterator<std::string>{in},
std::istream_iterator<std::string>{},
[&](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::uint64_t, std::uint64_t>
{
std::vector<std::uint32_t> patterns(std::size(entries));
std::vector<std::uint64_t> counts(19*19*19*19);
std::vector<bool> 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";
}

5
2024/CMakeLists.txt Normal file
View File

@ -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)

View File

@ -35,3 +35,4 @@ add_subdirectory(2020)
add_subdirectory(2021) add_subdirectory(2021)
add_subdirectory(2022) add_subdirectory(2022)
add_subdirectory(2023) add_subdirectory(2023)
add_subdirectory(2024)

View File

@ -7,6 +7,7 @@
#include <vector> #include <vector>
#include <boost/spirit/home/qi.hpp> #include <boost/spirit/home/qi.hpp>
#include <boost/fusion/include/boost_tuple.hpp>
namespace aocpp { namespace aocpp {
@ -46,6 +47,20 @@ auto ParseGrammar_(G const& grammar, std::istream & in) -> typename G::start_typ
return result; return result;
} }
template <typename P, typename R>
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<std::string::const_iterator, R()> 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 #endif