From 418b3c17748e10aab93cf7ce926aad325ca5cd38 Mon Sep 17 00:00:00 2001 From: Alex Karle Date: Fri, 3 Dec 2021 10:26:27 -0500 Subject: [PATCH] day3: Add speedy bit-shifting C implementation This was trickier than expected to write. I originally tried to flip gamma into epsilon with ~, but that flips all the leading bits too... Next problem was that I was |= 1< +#include + +#define MAX_WIDTH 32 + +int main(void) { + /* Key takeaway: if think of the input as a matrix, we can + * sum the columns and count the number of entries and know + * that if N entries had X sum, there's X 1's and N-X 0's. + */ + int counts[MAX_WIDTH] = { 0 }; + int c; + int col = 0; + int n = 0; + while ((c = getchar()) != EOF) { + switch (c) { + case '0': + col++; + break; + case '1': + counts[col]++; + col++; + break; + case '\n': + /* reset the column */ + col = 0; + n++; + break; + default: + fprintf(stderr, "bad input"); + exit(1); + break; + } + } + + /* convert counts into a bitmask of 1/0 based on which was max */ + unsigned int gamma = 0; + unsigned int eps = 0; + for (int i = 0; i < MAX_WIDTH; i++) { + if (counts[i] == 0) { + /* assume we see each at least once, so this was the end of width */ + break; + } + /* boost the last value to make room for more! */ + gamma <<= 1; + eps <<= 1; + if (counts[i] > n / 2) { + gamma |= 1; + } else { + eps |= 1; + } + } + printf("%u\n", eps * gamma); + return 0; +} diff --git a/Makefile b/Makefile index 7f29a52..5fe10ec 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ CFLAGS = -g -O2 -Wall -Wpedantic -Wextra DAY = * -TARGETS = 1/a 1/b 2/a 2/b +TARGETS = 1/a 1/b 2/a 2/b 3/a .PHONY: build build: $(TARGETS) -- libgit2 1.8.1