diff options
Diffstat (limited to '2020')
-rw-r--r-- | 2020/day14.c | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/2020/day14.c b/2020/day14.c index f04e864..a40bb3f 100644 --- a/2020/day14.c +++ b/2020/day14.c @@ -1,7 +1,7 @@ #include <stdio.h> #include <stdlib.h> typedef unsigned long ul; -static struct { +static struct Write { ul addr; ul val; } writes[1024]; @@ -16,6 +16,18 @@ static void write(ul addr, ul val) { writes[len].addr = addr; writes[len++].val = val; } +static struct Write writes2[0xFFFFFFFFF]; +static ul len2; +static void write2(ul addr, ul val) { + for (int i = 0; i < len2; ++i) { + if (writes2[i].addr == addr) { + writes2[i].val = val; + return; + } + } + writes2[len2].addr = addr; + writes2[len2++].val = val; +} int main(void) { ul mask = 0; ul bits = 0; @@ -37,9 +49,21 @@ int main(void) { ul addr, val; n = scanf("em[%lu] = %lu\n", &addr, &val); if (n < 2) break; - val &= mask; - val |= bits; - write(addr, val); + write(addr, (val & mask) | bits); + addr |= bits; + addr &= ~mask; + ul writes = 1UL << __builtin_popcountl(mask); + for (ul i = 0; i < writes; ++i) { + ul a = addr; + ul w = i; + for (int j = 0; j < 36; ++j) { + if (mask & (1UL << j)) { + a |= (w & 1) << j; + w >>= 1; + } + } + write2(a, val); + } } } ul sum = 0; @@ -47,4 +71,9 @@ int main(void) { sum += writes[i].val; } printf("%lu\n", sum); + sum = 0; + for (ul i = 0; i < len2; ++i) { + sum += writes2[i].val; + } + printf("%lu\n", sum); } |