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