diff options
| author | Thomas Schmucker <ts@its1.de> | 2023-12-31 09:37:52 +0100 |
|---|---|---|
| committer | Thomas Schmucker <ts@its1.de> | 2023-12-31 09:37:52 +0100 |
| commit | 43e8adeff6306073bf58631be796f409f293997f (patch) | |
| tree | a928a47af5ce040a4868da54d6970671237ec92f | |
| parent | 0d06788586cda1b1ba01524f4ba3cad147052203 (diff) | |
| download | advent-of-code-43e8adeff6306073bf58631be796f409f293997f.tar.gz advent-of-code-43e8adeff6306073bf58631be796f409f293997f.tar.bz2 advent-of-code-43e8adeff6306073bf58631be796f409f293997f.zip | |
Lösungen für Tag 24, Teil 2 (mit Z3 als Solver :/ ...)
| -rw-r--r-- | compile_flags.txt | 1 | ||||
| -rw-r--r-- | makefile | 3 | ||||
| -rw-r--r-- | src/day24.cpp | 42 | ||||
| -rw-r--r-- | src/day24.py | 33 |
4 files changed, 46 insertions, 33 deletions
diff --git a/compile_flags.txt b/compile_flags.txt index 966e06b..0000d86 100644 --- a/compile_flags.txt +++ b/compile_flags.txt | |||
| @@ -5,3 +5,4 @@ | |||
| 5 | -Wdouble-promotion | 5 | -Wdouble-promotion |
| 6 | -pedantic | 6 | -pedantic |
| 7 | -std=c++20 | 7 | -std=c++20 |
| 8 | -I/usr/local/include | ||
| @@ -31,6 +31,9 @@ bin: | |||
| 31 | bin/%: src/%.cpp | bin | 31 | bin/%: src/%.cpp | bin |
| 32 | c++ $(CPPFLAGS) $^ -o $@ | 32 | c++ $(CPPFLAGS) $^ -o $@ |
| 33 | 33 | ||
| 34 | bin/day24: src/day24.cpp | bin | ||
| 35 | c++ $(CPPFLAGS) -Wno-sign-conversion -I/usr/local/include $^ -L/usr/local/lib -lz3 -o $@ | ||
| 36 | |||
| 34 | clean: | 37 | clean: |
| 35 | rm -rf bin | 38 | rm -rf bin |
| 36 | 39 | ||
diff --git a/src/day24.cpp b/src/day24.cpp index 296d38a..76f459b 100644 --- a/src/day24.cpp +++ b/src/day24.cpp | |||
| @@ -2,9 +2,12 @@ | |||
| 2 | #include <fstream> | 2 | #include <fstream> |
| 3 | #include <iostream> | 3 | #include <iostream> |
| 4 | #include <limits> | 4 | #include <limits> |
| 5 | #include <map> | ||
| 5 | #include <string> | 6 | #include <string> |
| 6 | #include <tuple> | 7 | #include <tuple> |
| 7 | #include <vector> | 8 | #include <vector> |
| 9 | #include <z3++.h> | ||
| 10 | |||
| 8 | using namespace std; | 11 | using namespace std; |
| 9 | 12 | ||
| 10 | using line_type = tuple<double, double, double, double, double, double>; | 13 | using line_type = tuple<double, double, double, double, double, double>; |
| @@ -122,10 +125,49 @@ part1(const puzzle_type& input) | |||
| 122 | cout << sum << endl; | 125 | cout << sum << endl; |
| 123 | } | 126 | } |
| 124 | 127 | ||
| 128 | void | ||
| 129 | part2(const puzzle_type& input) | ||
| 130 | { | ||
| 131 | auto config = z3::config(); | ||
| 132 | auto context = z3::context(config); | ||
| 133 | auto solver = z3::solver(context); | ||
| 134 | |||
| 135 | const auto px = context.int_const("px"); | ||
| 136 | const auto py = context.int_const("py"); | ||
| 137 | const auto pz = context.int_const("pz"); | ||
| 138 | const auto vx = context.int_const("vx"); | ||
| 139 | const auto vy = context.int_const("vy"); | ||
| 140 | const auto vz = context.int_const("vz"); | ||
| 141 | |||
| 142 | for ( size_t i = 0; i != input.size(); ++i ) { | ||
| 143 | const auto& stone = input[i]; | ||
| 144 | |||
| 145 | const auto pxn = context.int_val(int64_t(get<0>(stone))); | ||
| 146 | const auto pyn = context.int_val(int64_t(get<1>(stone))); | ||
| 147 | const auto pzn = context.int_val(int64_t(get<2>(stone))); | ||
| 148 | const auto vxn = context.int_val(int64_t(get<3>(stone))); | ||
| 149 | const auto vyn = context.int_val(int64_t(get<4>(stone))); | ||
| 150 | const auto vzn = context.int_val(int64_t(get<5>(stone))); | ||
| 151 | const auto tn = context.int_const(to_string(i+1).c_str()); | ||
| 152 | |||
| 153 | solver.add(tn >= 0); | ||
| 154 | solver.add(pxn + vxn * tn == px + vx * tn); | ||
| 155 | solver.add(pyn + vyn * tn == py + vy * tn); | ||
| 156 | solver.add(pzn + vzn * tn == pz + vz * tn); | ||
| 157 | } | ||
| 158 | |||
| 159 | solver.check(); | ||
| 160 | |||
| 161 | auto model = solver.get_model(); | ||
| 162 | |||
| 163 | cout << model.eval(px).as_int64() + model.eval(py).as_int64() + model.eval(pz).as_int64() << endl; | ||
| 164 | } | ||
| 165 | |||
| 125 | int | 166 | int |
| 126 | main() | 167 | main() |
| 127 | { | 168 | { |
| 128 | const auto input = read_file("data/day24.txt"); | 169 | const auto input = read_file("data/day24.txt"); |
| 129 | 170 | ||
| 130 | part1(input); | 171 | part1(input); |
| 172 | part2(input); | ||
| 131 | } | 173 | } |
diff --git a/src/day24.py b/src/day24.py deleted file mode 100644 index 809f2d0..0000000 --- a/src/day24.py +++ /dev/null | |||
| @@ -1,33 +0,0 @@ | |||
| 1 | class Hailstone: | ||
| 2 | def __init__(self, sx, sy, sz, vx, vy, vz): | ||
| 3 | self.sx = sx | ||
| 4 | self.sy = sy | ||
| 5 | self.sz = sz | ||
| 6 | self.vx = vx | ||
| 7 | self.vy = vy | ||
| 8 | self.vz = vz | ||
| 9 | |||
| 10 | self.a = vy | ||
| 11 | self.b = -vx | ||
| 12 | self.c = vy * sx - vx * sy | ||
| 13 | |||
| 14 | def __repr__(self): | ||
| 15 | return "Hailstone{" + f"a={self.a}, b={self.b}, c={self.c}" + "}" | ||
| 16 | |||
| 17 | hailstones = [Hailstone(*map(int, line.replace("@", ",").split(","))) for line in open("data/day24.txt")] | ||
| 18 | |||
| 19 | total = 0 | ||
| 20 | |||
| 21 | for i, hs1 in enumerate(hailstones): | ||
| 22 | for hs2 in hailstones[:i]: | ||
| 23 | a1, b1, c1 = hs1.a, hs1.b, hs1.c | ||
| 24 | a2, b2, c2 = hs2.a, hs2.b, hs2.c | ||
| 25 | if a1 * b2 == b1 * a2: | ||
| 26 | continue | ||
| 27 | x = (c1 * b2 - c2 * b1) / (a1 * b2 - a2 * b1) | ||
| 28 | y = (c2 * a1 - c1 * a2) / (a1 * b2 - a2 * b1) | ||
| 29 | if 200000000000000 <= x <= 400000000000000 and 200000000000000 <= y <= 400000000000000: | ||
| 30 | if all((x - hs.sx) * hs.vx >= 0 and (y - hs.sy) * hs.vy >= 0 for hs in (hs1, hs2)): | ||
| 31 | total += 1 | ||
| 32 | |||
| 33 | print(total) | ||
