#include #include #include /* A place for carts to go */ #define MAX_WIDTH 256 #define MAX_HEIGHT 256 static char playfield[MAX_HEIGHT][MAX_WIDTH]; /* Some carts to go in the place */ #define MAX_CARTS 256 static int num_carts = 0; static struct cart { short x; short y; char dir; char turn; char under; } carts[MAX_CARTS]; static const char cart_dirs[] = ">^y - cart_b->y; if (!result) result = cart_a->x - cart_b->x; return result; } /* Sort carts */ void sort_carts() { qsort(carts, num_carts, sizeof (struct cart), cartcmp); } /* A way to look at all that stuff */ void show_playfield() { for (char *p = *playfield; *p; p += MAX_WIDTH) { printf("%s", p); } putchar('\n'); } void show_carts() { if (num_carts) { for (int i = 0; i < num_carts; i++) { struct cart *p = &carts[i]; printf("%c%c%d,%d ", cart_dirs[p->dir], cart_turns[p->turn], p->x, p->y ); } putchar('\n'); } } /* Enough messing about */ #define IO_ERROR 2 #define BAD_INPUT 1 int main(int argc, char *argv[]) { struct cart *cart; /* Read input map and locate carts */ { FILE *input = fopen(argc > 1? argv[1]: "input.txt", "r"); int error = IO_ERROR; if (input) { error = BAD_INPUT; for (int row = 0; row < MAX_HEIGHT - 1; row++) { char *buf = playfield[row]; if (fgets(buf, MAX_WIDTH, input)) { if (buf[strlen(buf) - 1] != '\n') break; char *p = buf; while (p = strpbrk(p, cart_dirs)) { cart = &carts[num_carts++]; cart->x = p - buf; cart->y = row; cart->dir = strchr(cart_dirs, *p++) - cart_dirs; cart->turn = 0; cart->under = track_dirs[cart->dir]; } } else { error = 0; break; } } fclose(input); } if (error) return error; } if (0) show_carts(); if (0) show_playfield(); /* Update cart locations until one crashes */ for (;;) { for (cart = carts; cart < carts + num_carts; cart++) { const static int cos[] = {1, 0, -1, 0, 1}; const static int *sin = cos + 1; playfield[cart->y][cart->x] = cart->under; cart->x += cos[cart->dir]; cart->y += sin[cart->dir]; cart->under = playfield[cart->y][cart->x]; switch (cart->under) { case '+': cart->dir = (cart->dir + 1 - cart->turn) & 3; cart->turn = (cart->turn + 1) % 3; break; case '/': cart->dir ^= 1; break; case '\\': cart->dir ^= 3; break; case '|': if (!(cart->dir & 1)) goto crash; break; case '-': if (cart->dir & 1) goto crash; break; default: goto crash; } playfield[cart->y][cart->x] = cart_dirs[cart->dir]; } sort_carts(); if (0) show_carts(); if (0) show_playfield(); } crash: playfield[cart->y][cart->x] = 'X'; if (0) show_playfield(); printf("%d,%d\n", cart->x, cart->y); return 0; }