summary refs log tree commit diff homepage
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2020-12-14 00:53:21 -0500
committerJune McEnroe <june@causal.agency>2020-12-14 00:53:21 -0500
commit0dfe76d562b6176654e6753b8bcc7be21becb025 (patch)
treee68671ca6cf6ba7e64596a8a286a7d427b0a1974
parentSolve day 14 part 1 (diff)
downloadaoc-0dfe76d562b6176654e6753b8bcc7be21becb025.tar.gz
aoc-0dfe76d562b6176654e6753b8bcc7be21becb025.zip
Solve day 14 part 2
Quite messy but it works.
-rw-r--r--2020/day14.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/2020/day14.c b/2020/day14.c
index f04e864..a40bb3f 100644
--- a/2020/day14.c
+++ b/2020/day14.c
@@ -1,7 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 typedef unsigned long ul;
-static struct {
+static struct Write {
 	ul addr;
 	ul val;
 } writes[1024];
@@ -16,6 +16,18 @@ static void write(ul addr, ul val) {
 	writes[len].addr = addr;
 	writes[len++].val = val;
 }
+static struct Write writes2[0xFFFFFFFFF];
+static ul len2;
+static void write2(ul addr, ul val) {
+	for (int i = 0; i < len2; ++i) {
+		if (writes2[i].addr == addr) {
+			writes2[i].val = val;
+			return;
+		}
+	}
+	writes2[len2].addr = addr;
+	writes2[len2++].val = val;
+}
 int main(void) {
 	ul mask = 0;
 	ul bits = 0;
@@ -37,9 +49,21 @@ int main(void) {
 			ul addr, val;
 			n = scanf("em[%lu] = %lu\n", &addr, &val);
 			if (n < 2) break;
-			val &= mask;
-			val |= bits;
-			write(addr, val);
+			write(addr, (val & mask) | bits);
+			addr |= bits;
+			addr &= ~mask;
+			ul writes = 1UL << __builtin_popcountl(mask);
+			for (ul i = 0; i < writes; ++i) {
+				ul a = addr;
+				ul w = i;
+				for (int j = 0; j < 36; ++j) {
+					if (mask & (1UL << j)) {
+						a |= (w & 1) << j;
+						w >>= 1;
+					}
+				}
+				write2(a, val);
+			}
 		}
 	}
 	ul sum = 0;
@@ -47,4 +71,9 @@ int main(void) {
 		sum += writes[i].val;
 	}
 	printf("%lu\n", sum);
+	sum = 0;
+	for (ul i = 0; i < len2; ++i) {
+		sum += writes2[i].val;
+	}
+	printf("%lu\n", sum);
 }