Skip to content

Commit 304efd3

Browse files
author
Christian Lundh
committed
C++23 2024 day 13
Fun vith views. Not very efficient I suppose
1 parent 77fd39b commit 304efd3

File tree

3 files changed

+119
-1
lines changed

3 files changed

+119
-1
lines changed

C++/2024/aoc_2024_13.cpp

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#include "aoc_io.hpp"
2+
#include "aoc_timer.hpp"
3+
#include <algorithm>
4+
#include <cstdint>
5+
#include <iterator>
6+
#include <ranges>
7+
#include <string>
8+
#include <vector>
9+
10+
template <class T>
11+
auto divmod(T &&a, T &&b) -> std::pair<T, T> {
12+
return {a / b, a % b};
13+
}
14+
15+
using Equation = std::vector<int>;
16+
[[nodiscard]] auto parse_instructions(const std::vector<std::string> &instructions) -> std::vector<Equation> {
17+
auto rng = instructions //
18+
| std::views::split(std::string{}) // -> vec<vec<string>>
19+
| std::views::transform([](const auto &group) {
20+
auto rng = group //
21+
| std::views::transform([](const auto &substring) {
22+
auto numbers = substring //
23+
| std::views::filter([](const auto &c) {
24+
return std::isdigit(c) || (c == ',');
25+
}) //
26+
| std::ranges::to<std::string>();
27+
return numbers;
28+
});
29+
return rng;
30+
}) //
31+
| std::views::transform([](const auto group) {
32+
auto int_range = group // group = vec<std::string>
33+
| std::views::transform([](const auto &substring) {
34+
auto nn = substring //
35+
| std::views::split(',') //
36+
| std::views::transform([i = 0](const auto &s) mutable {
37+
auto str = std::string(s.begin(), s.end());
38+
auto return_string = std::format("'{}' {} [{}]", str, std::stoi(str), i++);
39+
return std::stoi(str);
40+
}); //
41+
return nn | std::ranges::to<std::vector>();
42+
});
43+
return int_range;
44+
}) //
45+
| std::views::transform([](const auto &subrange) {
46+
auto joined_range = subrange //
47+
| std::views::join //
48+
| std::ranges::to<std::vector>();
49+
return joined_range;
50+
});
51+
auto vec = std::vector<Equation>{};
52+
std::ranges::transform(rng, std::back_inserter(vec), [](const auto &r) {
53+
auto v = std::vector<int>(r.begin(), r.end());
54+
return v;
55+
});
56+
return vec;
57+
}
58+
59+
[[nodiscard]] auto solver(const std::vector<Equation> &instructions, uint64_t delta) -> uint64_t {
60+
auto result = uint64_t{};
61+
for (auto &equation : instructions) {
62+
int64_t x0 = equation[0];
63+
int64_t y0 = equation[1];
64+
int64_t x1 = equation[2];
65+
int64_t y1 = equation[3];
66+
int64_t cx = equation[4] + delta;
67+
int64_t cy = equation[5] + delta;
68+
69+
auto [a_presses, a_remainder] = divmod(cx * y1 - cy * x1, y1 * x0 - x1 * y0);
70+
if (a_remainder != 0)
71+
continue;
72+
auto [b_presses, b_remainder] = divmod(-cx * y0 + cy * x0, y1 * x0 - x1 * y0);
73+
if (b_remainder != 0)
74+
continue;
75+
76+
result += 3 * a_presses + b_presses;
77+
}
78+
return result;
79+
}
80+
81+
[[nodiscard]] auto solve_part_1(const std::vector<Equation> &instructions) -> uint32_t {
82+
return solver(instructions, 0);
83+
}
84+
85+
[[nodiscard]] auto solve_part_2(const std::vector<Equation> &instructions) -> uint64_t {
86+
constexpr uint64_t delta = 10000000000000;
87+
return solver(instructions, delta);
88+
}
89+
void solve_all(const std::vector<std::string> &instructions) {
90+
auto parsed_instructions = aoc::timer(parse_instructions, instructions, "Preparation time:");
91+
aoc::timer(1, solve_part_1, parsed_instructions);
92+
aoc::timer(2, solve_part_2, parsed_instructions);
93+
}
94+
95+
auto main(int argc, char **argv) -> int {
96+
std::string filename;
97+
constexpr int year = 2024;
98+
constexpr int day = 13;
99+
100+
auto args = std::span(argv, argc);
101+
if (argc > 1) {
102+
if (std::string(args[1]) == "--test") {
103+
filename = "test_input.txt";
104+
} else {
105+
filename = args[1];
106+
}
107+
} else {
108+
filename = "input.txt";
109+
}
110+
111+
auto instructions = aoc::io::get_input_list<std::string>(filename, year, day);
112+
113+
aoc::io::header(year, day);
114+
aoc::timer(solve_all, instructions);
115+
116+
return 0;
117+
}

C++/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ While I try to learn the benefits and caveats of C++ I also decided to take on t
1717
| 9 | &#11088;&#11088; | | |
1818
| 10 | &#11088;&#11088; | | |
1919
| 11 | &#11088;&#11088; | | |
20+
| 13 | &#11088;&#11088; | | |
2021
| 14 | &#11088;&#11088; | | |
2122

2223
## 2023:

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Solutions for [Advent of Code](https://adventofcode.com) in different languages.
55
## Year 2024
66
+ 22 &#11088; in [Python](python/README.md)
77
+ 17 &#11088; in [C](C/README.md)
8-
+ 22 &#11088; in [C++](C++/README.md)
8+
+ 24 &#11088; in [C++](C++/README.md)
99
+ 1 &#11088; in [Rust](Rust/README.md)
1010

1111
## Year 2023

0 commit comments

Comments
 (0)