diff options
author | kaiwu <kaiwu2004@gmail.com> | 2023-01-08 16:46:49 +0800 |
---|---|---|
committer | kaiwu <kaiwu2004@gmail.com> | 2023-01-08 16:46:49 +0800 |
commit | b3ca69c9639f41ab234d1a3917b5c83a41577328 (patch) | |
tree | c778861bae86f638b244eba27987708dc9ff1806 /src/2022/day17/aoc.cpp | |
parent | 83c8d504b055b278ef05f5726455e512a46efdae (diff) | |
download | advent-of-code-b3ca69c9639f41ab234d1a3917b5c83a41577328.tar.gz advent-of-code-b3ca69c9639f41ab234d1a3917b5c83a41577328.zip |
2022 day17 part1
Diffstat (limited to 'src/2022/day17/aoc.cpp')
-rw-r--r-- | src/2022/day17/aoc.cpp | 146 |
1 files changed, 88 insertions, 58 deletions
diff --git a/src/2022/day17/aoc.cpp b/src/2022/day17/aoc.cpp index d7a1099..28a171f 100644 --- a/src/2022/day17/aoc.cpp +++ b/src/2022/day17/aoc.cpp @@ -4,7 +4,7 @@ namespace aoc2022 { static line_view moves; -static uint8_t at(uint8_t r, int p) { +static bool at(uint8_t r, int p) { // p 0..7 uint8_t m = 0x01; while (p-- > 0) @@ -14,14 +14,15 @@ static uint8_t at(uint8_t r, int p) { char next() { static int i{0}; - i %= (moves.length - 1); + int x = i++ % (moves.length - 1); const char* p = moves.line; - return *(p + i++); + printf("%c at %d\n", *(p + x), x); + return *(p + x); } -void print(const rock17& r) { - for (size_t i = r.rs.size(); i > 0; i--) { - uint8_t x = r.rs[i - 1]; +void print(std::vector<uint8_t>& rs) { + for (size_t i = rs.size(); i > 0; i--) { + uint8_t x = rs[i - 1]; int c{6}; while (c >= 0) { printf("%c", at(x, c) ? '#' : '.'); @@ -67,31 +68,23 @@ rock17 make_rock(int i) { rock17 right(rock17 r) { switch (r.type) { case r1: - if (at(r.rs[0], 0) == 0) { - r.rs[0] >>= 1; - } + r.rs[0] >>= 1; break; case r2: case r3: - if (at(r.rs[1], 0) == 0) { - r.rs[0] >>= 1; - r.rs[1] >>= 1; - r.rs[2] >>= 1; - } + r.rs[0] >>= 1; + r.rs[1] >>= 1; + r.rs[2] >>= 1; break; case r4: - if (at(r.rs[0], 0) == 0) { - r.rs[0] >>= 1; - r.rs[1] >>= 1; - r.rs[2] >>= 1; - r.rs[3] >>= 1; - } + r.rs[0] >>= 1; + r.rs[1] >>= 1; + r.rs[2] >>= 1; + r.rs[3] >>= 1; break; case r5: - if (at(r.rs[0], 0) == 0) { - r.rs[0] >>= 1; - r.rs[1] >>= 1; - } + r.rs[0] >>= 1; + r.rs[1] >>= 1; break; default: break; @@ -102,37 +95,27 @@ rock17 right(rock17 r) { rock17 left(rock17 r) { switch (r.type) { case r1: - if (at(r.rs[0], 6) == 0) { - r.rs[0] <<= 1; - } + r.rs[0] <<= 1; break; case r2: - if (at(r.rs[1], 6) == 0) { - r.rs[0] <<= 1; - r.rs[1] <<= 1; - r.rs[2] <<= 1; - } + r.rs[0] <<= 1; + r.rs[1] <<= 1; + r.rs[2] <<= 1; break; case r3: - if (at(r.rs[0], 6) == 0) { - r.rs[0] <<= 1; - r.rs[1] <<= 1; - r.rs[2] <<= 1; - } + r.rs[0] <<= 1; + r.rs[1] <<= 1; + r.rs[2] <<= 1; break; case r4: - if (at(r.rs[0], 6) == 0) { - r.rs[0] <<= 1; - r.rs[1] <<= 1; - r.rs[2] <<= 1; - r.rs[3] <<= 1; - } + r.rs[0] <<= 1; + r.rs[1] <<= 1; + r.rs[2] <<= 1; + r.rs[3] <<= 1; break; case r5: - if (at(r.rs[0], 6) == 0) { - r.rs[0] <<= 1; - r.rs[1] <<= 1; - } + r.rs[0] <<= 1; + r.rs[1] <<= 1; break; default: break; @@ -142,14 +125,51 @@ rock17 left(rock17 r) { bool collide(uint8_t r1, uint8_t r2) { return r1 & r2; } +bool collide_left(std::vector<uint8_t>& rs1, std::vector<uint8_t>& rs2) { + for (size_t j = 0; j < rs1.size(); j++) { + for (int i = 6; i >= 0; i--) { + if (at(rs1[j], i) && (i == 6 || at(rs2[j + 1], i + 1))) { + return true; + } + } + } + return false; +} + +bool collide_right(std::vector<uint8_t>& rs1, std::vector<uint8_t>& rs2) { + for (size_t j = 0; j < rs1.size(); j++) { + for (int i = 0; i <= 6; i++) { + if (at(rs1[j], i) && (i == 0 || at(rs2[j + 1], i - 1))) { + return true; + } + } + } + return false; +} + +bool collide_down(std::vector<uint8_t>& rs1, std::vector<uint8_t>& rs2) { return collide(rs1[0], rs2[0]); } + void merge(rock17& floor, rock17 r, int n) { + std::vector<uint8_t> room; + for (size_t i = floor.rs.size() - n - 1; room.size() < r.rs.size() + 1 && i < floor.rs.size(); i++) { + room.push_back(floor.rs[i]); + } + + while (room.size() < r.rs.size() + 1) { + room.push_back(0x00); + } + auto m = next(); - printf("%c %d\n", m, r.type); - r = m == '>' ? right(r) : left(r); + if (m == '>' && !collide_right(r.rs, room)) { + // printf("%c %d\n", m, r.type); + r = right(r); + } + if (m == '<' && !collide_left(r.rs, room)) { + // printf("%c %d\n", m, r.type); + r = left(r); + } - uint8_t rt = floor.rs[floor.rs.size() - 1 - n]; - uint8_t rh = r.rs[0]; - if (!collide(rt, rh)) { + if (!collide_down(r.rs, room)) { merge(floor, r, n + 1); } else { // merge from n to last with r size_t m{0}; @@ -165,21 +185,31 @@ void merge(rock17& floor, rock17 r, int n) { } } +void check_three(std::vector<uint8_t>& rs) { + auto n = 0; + while (rs[rs.size() - n - 1] == 0x00) { + n++; + } + + auto needed = 3 - n; + while (needed-- > 0) { + rs.push_back(0x00); + } +} + std::pair<int, int> day17(line_view file) { moves = file; rock17 floor{chamber, {0x7F}}; - int n{3}; + int n{10}; for (int i = 0; i < n; i++) { rock17 r = make_rock(i); - auto three{3}; - while (three-- > 0) { - floor.rs.push_back(0x00); - } + check_three(floor.rs); merge(floor, r, 0); } + print(floor.rs); + printf("%ld\n", floor.rs.size() - 4); - print(floor); return {0, 0}; } } // namespace aoc2022 |