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