diff options
author | June McEnroe <june@causal.agency> | 2021-12-04 18:00:33 -0500 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2021-12-04 18:00:33 -0500 |
commit | b0375eadc406bdb57a41653996637a72b3318d4a (patch) | |
tree | 3a4d356ec5a659a90cfd20d5e3096ad53da24540 /2021 | |
parent | Refactor day 3 using grep to count ones (diff) | |
download | aoc-b0375eadc406bdb57a41653996637a72b3318d4a.tar.gz aoc-b0375eadc406bdb57a41653996637a72b3318d4a.zip |
Solve day 4 part 1
Gave up on perl and then spent way too long trying to get this parsed correctly in C. This code is pretty bad even for AoC.
Diffstat (limited to '')
-rw-r--r-- | 2021/day04.c | 53 |
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); +} |