09: Solve in C
This commit is contained in:
parent
c35655cd99
commit
668630b712
|
@ -0,0 +1,83 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
Loading…
Reference in New Issue