From: Mart Lubbers Date: Tue, 14 Dec 2021 10:04:11 +0000 (+0100) Subject: optimise day four X-Git-Url: https://git.martlubbers.net/?a=commitdiff_plain;h=92dd974e7abf6a1afa2def91724ab67f54bc5767;p=advent21.git optimise day four --- diff --git a/14a.c b/14a.c index 7b52084..10dea23 100644 --- a/14a.c +++ b/14a.c @@ -1,58 +1,63 @@ #include #include #include +#include -#include +struct template { char x1; char x2; char ins; }; -struct pair { char x; char y; }; -struct template { struct pair key; char ins; UT_hash_handle hh; }; +#define lookup(i, x1, x2) (i)[((x1)-'A')+((x2)-'A')*26] int main() { - char *input = NULL, *buf = NULL, *oldinput = NULL; - size_t inputlen = 0, len; - struct template *template = NULL; + char *buf = NULL; + size_t len; + int ntemplate = 0; + struct template template[100]; + unsigned long input1[26*26] = {0}, input2[26*26] = {0}; + unsigned long *input = input1, *newinput = input2; + + int first = getchar(); + int c, last = first; + unsigned long freq[26] = {0}; + while ( (c = getchar()) != '\n') { + lookup(input, last, c) = 1; + last = c; + } - if (getline(&input, &inputlen, stdin) == -1) - return 1; while (getline(&buf, &len, stdin) != -1) { - if (strcmp(buf, "\n") == 0) + if (buf[0] == '\n') continue; - struct template *t = calloc(1, sizeof(struct template)); - t->key.x = buf[0]; - t->key.y = buf[1]; - t->ins = buf[6]; - HASH_ADD(hh, template, key, sizeof(struct pair), t); + template[ntemplate++] = (struct template) + {.x1=buf[0], .x2=buf[1], .ins=buf[6]}; } - for (int i = 0; i<20; i++) { - free(oldinput); - oldinput = input; - input = malloc(inputlen *= 2); - inputlen = 0; - char *c; - for (c = &oldinput[0]; *c != '\0'; c++) { - input[inputlen++] = *c; - struct pair p = {.x=c[0], .y=c[1]}; - struct template *t; - HASH_FIND(hh, template, &p, sizeof(struct pair), t); - if (t) - input[inputlen++] = t->ins; + for (int step = 0; step < 10; step++) { + for (int i = 0; i mcommon) - mcommon = freq[i]; - if (freq[i] > 1 && freq[i] < lcommon) - lcommon = freq[i]; + freq[first-'A']++; + freq[last-'A']++; + + unsigned long min = ULONG_MAX, max = 0; + for (int i = 0; i<26; i++) { + max = freq[i] > max ? freq[i] : max; + min = freq[i] > 1 && freq[i] < min ? freq[i] : min; } - printf("%d\n", mcommon-lcommon); + printf("%lu\n", max/2-min/2); } diff --git a/14b.c b/14b.c index 83ebab0..2b505fa 100644 --- a/14b.c +++ b/14b.c @@ -3,42 +3,40 @@ #include #include +struct template { char x1; char x2; char ins; }; + #define lookup(i, x1, x2) (i)[((x1)-'A')+((x2)-'A')*26] int main() { char *buf = NULL; size_t len; - char template[26*26] = {0}; - unsigned long input1[26*26] = {0}; - unsigned long input2[26*26] = {0}; - unsigned long *input = input1; - unsigned long *newinput = input2; + int ntemplate = 0; + struct template template[100]; + unsigned long input1[26*26] = {0}, input2[26*26] = {0}; + unsigned long *input = input1, *newinput = input2; int first = getchar(); - int c, oldc = first; + int c, last = first; unsigned long freq[26] = {0}; while ( (c = getchar()) != '\n') { - lookup(input, oldc, c) = 1; - oldc = c; + lookup(input, last, c) = 1; + last = c; } while (getline(&buf, &len, stdin) != -1) { if (buf[0] == '\n') continue; - lookup(template, buf[0], buf[1]) = buf[6]; + template[ntemplate++] = (struct template) + {.x1=buf[0], .x2=buf[1], .ins=buf[6]}; } for (int step = 0; step < 40; step++) { - for (char x = 'A'; x<='Z'; x++) { - for (char y = 'A'; y<='Z'; y++) { - char ins = lookup(template, x, y); - if (ins != '\0') { - unsigned long freq = lookup(input, x, y); - lookup(newinput, x, ins) += freq; - lookup(newinput, ins, y) += freq; - } - } + for (int i = 0; i