aboutsummaryrefslogtreecommitdiff
path: root/src/2022/day17/aoc.cpp
diff options
context:
space:
mode:
authorkaiwu <kaiwu2004@gmail.com>2023-01-08 16:46:49 +0800
committerkaiwu <kaiwu2004@gmail.com>2023-01-08 16:46:49 +0800
commitb3ca69c9639f41ab234d1a3917b5c83a41577328 (patch)
treec778861bae86f638b244eba27987708dc9ff1806 /src/2022/day17/aoc.cpp
parent83c8d504b055b278ef05f5726455e512a46efdae (diff)
downloadadvent-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.cpp146
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