summary refs log tree commit diff homepage
diff options
context:
space:
mode:
-rw-r--r--2021/day14.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/2021/day14.c b/2021/day14.c
new file mode 100644
index 0000000..7525bd8
--- /dev/null
+++ b/2021/day14.c
@@ -0,0 +1,48 @@
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+static struct {
+	char a, b, c;
+} pairs[128];
+static size_t len;
+static char *step(const char *prev) {
+	char *next = malloc(1 + strlen(prev)*2);
+	char *ptr = next;
+	size_t i;
+	for (i = 0; prev[i+1]; ++i) {
+		*ptr++ = prev[i];
+		for (size_t j = 0; j < len; ++j) {
+			if (prev[i] != pairs[j].a || prev[i+1] != pairs[j].b) continue;
+			*ptr++ = pairs[j].c;
+			break;
+		}
+	}
+	*ptr++ = prev[i];
+	*ptr = '\0';
+	return next;
+}
+int main(void) {
+	size_t cap = 0;
+	char *polymer = NULL;
+	ssize_t n = getline(&polymer, &cap, stdin);
+	if (polymer[n-1] == '\n') polymer[n-1] = '\0';
+	while (EOF != scanf(" %c%c -> %c\n", &pairs[len].a, &pairs[len].b, &pairs[len].c)) {
+		len++;
+	}
+	for (int i = 0; i < 10; ++i) {
+		char *next = step(polymer);
+		free(polymer);
+		polymer = next;
+	}
+	int freq[128] = {0};
+	for (size_t i = 0; polymer[i]; ++i) {
+		freq[polymer[i]]++;
+	}
+	int min = INT_MAX, max = INT_MIN;
+	for (int i = 'A'; i <= 'Z'; ++i) {
+		if (freq[i] && freq[i] < min) min = freq[i];
+		if (freq[i] > max) max = freq[i];
+	}
+	printf("%d\n", max - min);
+}