Line data Source code
1 : #include "PuzzleImpl.h"
2 :
3 : #include "IntegerCast.h"
4 : #include "Parsing.h"
5 :
6 : #include <numeric>
7 : #include <ranges>
8 : #include <string>
9 : #include <unordered_map>
10 :
11 : namespace {
12 :
13 179971 : std::optional<std::pair<uint64_t, uint64_t>> split(uint64_t const x) {
14 179971 : static std::array<char, std::numeric_limits<uint64_t>::digits10> buffer;
15 :
16 179971 : auto result = std::to_chars(buffer.data(), buffer.data() + buffer.size(), x);
17 179971 : ASSERT(result.ec == std::errc{});
18 179971 : std::string_view const s{buffer.data(), result.ptr};
19 :
20 179971 : if (s.size() % 2u != 0)
21 75478 : return std::nullopt;
22 :
23 104493 : std::pair<uint64_t, uint64_t> splitValues;
24 :
25 104493 : ASSERT(std::from_chars(s.data(), s.data() + s.size() / 2u, splitValues.first).ec == std::errc{});
26 104493 : ASSERT(std::from_chars(s.data() + s.size() / 2u, s.data() + s.size(), splitValues.second).ec ==
27 104493 : std::errc{});
28 :
29 104493 : return {splitValues};
30 179971 : }
31 :
32 2 : size_t run(std::string_view const input, size_t const times) {
33 2 : std::unordered_map<uint64_t, uint64_t> line, tmp;
34 :
35 2 : for (auto const &s : input | std::views::split(' ') |
36 16 : std::views::transform([](auto &&r) { return parseInt<uint64_t>(r); }))
37 16 : ++line[s];
38 :
39 102 : for (size_t i = 0; i < times; ++i) {
40 100 : for (auto &[key, value] : tmp)
41 174999 : value = 0u;
42 :
43 180069 : for (auto const &[x, count] : line) {
44 180069 : if (x == 0) {
45 98 : tmp[1] += count;
46 179971 : } else if (auto splitResult = split(x)) {
47 104493 : tmp[splitResult->first] += count;
48 104493 : tmp[splitResult->second] += count;
49 104493 : } else {
50 75478 : tmp[x * 2024u] += count;
51 75478 : }
52 180069 : }
53 :
54 100 : line.swap(tmp);
55 100 : }
56 :
57 2 : return std::transform_reduce(line.begin(), line.end(), uint64_t(0), std::plus{},
58 5151 : [&](auto const &p) { return p.second; });
59 2 : }
60 :
61 : } // namespace
62 :
63 1 : template <> std::string solvePart1<2024, 11>(std::string_view const input) {
64 1 : return std::to_string(run(input, 25u));
65 1 : }
66 :
67 1 : template <> std::string solvePart2<2024, 11>(std::string_view const input) {
68 1 : return std::to_string(run(input, 75u));
69 1 : }
|