diff options
author | Marvin Borner | 2021-12-14 15:53:56 +0100 |
---|---|---|
committer | Marvin Borner | 2021-12-14 15:57:55 +0100 |
commit | 883d350d37b4802a2569772853e1ea2a967972d0 (patch) | |
tree | 88a0783ed94a74ed928e067971302e98cae56fd4 /2021/14/solve.c | |
parent | ed341f7f190cec49d0c3d6353f63234ce5b58bef (diff) |
hee
Diffstat (limited to '2021/14/solve.c')
-rw-r--r-- | 2021/14/solve.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/2021/14/solve.c b/2021/14/solve.c new file mode 100644 index 0000000..b8c49f0 --- /dev/null +++ b/2021/14/solve.c @@ -0,0 +1,99 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#define COUNT(a) ((int)(sizeof(a) / sizeof 0 [a])) + +#define FORLINE \ + char *line = NULL; \ + size_t len = 0; \ + while (getline(&line, &len, fp) != EOF) +#define FREELINE \ + if (line) \ + free(line) + +#define IDX(a, b) (((a) - 'A') * 26 + ((b) - 'A')) +#define LEFT(i) (((i) / 26) + 'A') +#define RIGHT(i) (((i) % 26) + 'A') +static void solve(FILE *fp) +{ + char input[32] = { 0 }; + char rules[26 * 26] = { 0 }; + + int klaus = 0; + FORLINE + { + if (!klaus) + strcpy(input, line); + else if (klaus >= 2) + rules[IDX(line[0], line[1])] = line[6]; + klaus++; + } + FREELINE; + + long pairs[26 * 26] = { 0 }; + long counts[26] = { 0 }; + + for (char *p = input; *p && *p != '\n'; p++) { + if (*(p + 1)) + pairs[IDX(*p, *(p + 1))] += 1; + counts[*p - 'A'] += 1; + } + + int start = 0, end = 10; +aah: + for (int i = start; i < end; i++) { + long new[26 * 26] = { 0 }; + for (int j = 0; j < COUNT(pairs); j++) { + char a = LEFT(j), b = RIGHT(j); + char insert = rules[IDX(a, b)]; + if (insert) { + new[IDX(a, insert)] += pairs[j]; + new[IDX(insert, b)] += pairs[j]; + counts[insert - 'A'] += pairs[j]; + } else { + new[j] = pairs[j]; + } + }; + + memcpy(pairs, new, sizeof(pairs)); + } + + long max = 0, min = 0x4242424242424242; + for (int i = 0; i < COUNT(counts); i++) { + if (!counts[i]) + continue; + + if (counts[i] > max) + max = counts[i]; + else if (counts[i] < min) + min = counts[i]; + } + + printf("%lu\n", max - min); + + if (start == 0) { + start = end; + end = 40; + goto aah; + } +} + +int main(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + + FILE *fp = fopen("input", "r"); + if (!fp) + exit(EXIT_FAILURE); + + clock_t tic = clock(); + solve(fp); + clock_t toc = clock(); + printf("TIME: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC); + + fclose(fp); + return 0; +} |