summary refs log tree commit diff homepage
diff options
context:
space:
mode:
-rw-r--r--2021/day04.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/2021/day04.c b/2021/day04.c
new file mode 100644
index 0000000..88bf80f
--- /dev/null
+++ b/2021/day04.c
@@ -0,0 +1,53 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+static struct Board {
+	int mark;
+	int nums[25];
+} boards[128];
+static int len;
+static int win(const struct Board *board) {
+	int row = 0x1F;
+	int col = 0x108421;
+	for (int i = 0; i < 5; ++i) {
+		if ((board->mark & row) == row) return 1;
+		if ((board->mark & col) == col) return 1;
+		row <<= 5;
+		col <<= 1;
+	}
+	return 0;
+}
+static int winner(void) {
+	for (int i = 0; i < len; ++i) {
+		if (win(&boards[i])) return i;
+	}
+	return -1;
+}
+int main(void) {
+	char *buf = NULL;
+	size_t cap = 0;
+	getline(&buf, &cap, stdin);
+	int n = 0;
+	int nums[128];
+	while (buf) {
+		nums[n++] = strtol(strsep(&buf, ","), NULL, 10);
+	}
+	for (int i = 0;; ++i) {
+		if (EOF == scanf(" %d", &boards[len].nums[i%25])) break;
+		if (i%25 == 24) len++;
+	}
+	int i, w;
+	for (i = 0; (w = winner()) < 0 && i < n; ++i) {
+		for (int j = 0; j < len; ++j) {
+			for (int k = 0; k < 25; ++k) {
+				if (boards[j].nums[k] == nums[i]) boards[j].mark |= 1 << k;
+			}
+		}
+	}
+	int num = nums[i-1];
+	int sum = 0;
+	for (int i = 0; i < 25; ++i) {
+		if (!(boards[w].mark & (1 << i))) sum += boards[w].nums[i];
+	}
+	printf("%d\n", sum * num);
+}