#include #include #include #include typedef struct pos { int32_t x; int32_t y; struct pos *next; } pos; #define TBL_CAP (0x01000193U+1) uint32_t fnv1a_32(pos p) { uint32_t h = 0x01000193U * (0x811c9dc5U ^ p.x); h = 0x01000193U * (h ^ p.y); return h % TBL_CAP; } int tbl_get(pos **t, pos p) { uint32_t idx = fnv1a_32(p); pos *itm = t[idx]; if (!itm) itm = t[idx] = calloc(1, sizeof(pos)); else if (itm->x != p.x || itm->y != p.y) { for (;;) { if (itm->next) { if (itm->next->x == p.x && itm->next->y == p.y) return 0; itm = itm->next; } else { itm = itm->next = calloc(1, sizeof(pos)); break; } } } else return 0; itm->x = p.x; itm->y = p.y; return 1; } int main(void) { uint32_t S = 0, G = 0; static pos *vS[TBL_CAP] = {0}; static pos *vG[TBL_CAP] = {0}; static pos rope[10] = {0}; char dir; int steps; while (scanf("%c %i\n", &dir, &steps) == 2) { for (uint32_t s = 0; s < steps; s++) { switch (dir) { case 'U': rope[0].y++; break; case 'D': rope[0].y--; break; case 'L': rope[0].x--; break; case 'R': rope[0].x++; break; } for (int r = 1; r < 10; r++) { if (rope[r].x != rope[r-1].x || rope[r].y != rope[r-1].y) { int32_t hdiff = rope[r-1].x - rope[r].x; int32_t vdiff = rope[r-1].y - rope[r].y; int diag = abs(hdiff) + abs(vdiff) > 2; rope[r].x += (hdiff > 1 || (hdiff > 0 && diag)); rope[r].x -= (hdiff < -1 || (hdiff < 0 && diag)); rope[r].y += (vdiff > 1 || (vdiff > 0 && diag)); rope[r].y -= (vdiff < -1 || (vdiff < 0 && diag)); } } S += tbl_get(vS, rope[1]); G += tbl_get(vG, rope[9]); } } printf("Silver: %u\nGold: %u\n", S, G); }