#include #include #include #define MAX_MAP_SIZE 256 typedef enum tile_type { GROUND, UP_DOWN, LEFT_RIGHT, UP_RIGHT, UP_LEFT, DOWN_LEFT, DOWN_RIGHT, START } tile_type_t; typedef struct tile { tile_type_t type; struct tile *links[2]; int part_of_loop; } tile_t; int main() { char *p, *buf, c; buf = (char *)malloc(MAX_MAP_SIZE); memset(buf, 0, MAX_MAP_SIZE); p = buf; tile_t map[MAX_MAP_SIZE][MAX_MAP_SIZE]; memset(map, 0, MAX_MAP_SIZE*MAX_MAP_SIZE*sizeof(tile_t)); int x = 0, y = 0; while ((c = getchar()) != EOF) { *p++ = c; if (c == '\n') { x = 0; p = buf; while (*p != '\n') { switch (*p) { case '.': map[x][y].type = GROUND; break; case '|': map[x][y].type = UP_DOWN; // UP if (y != 0) { map[x][y].links[0] = &map[x][y-1]; } // DOWN map[x][y].links[1] = &map[x][y+1]; break; case '-': map[x][y].type = LEFT_RIGHT; // LEFT if (x != 0) { map[x][y].links[0] = &map[x-1][y]; } // RIGHT map[x][y].links[1] = &map[x+1][y]; break; case 'L': map[x][y].type = UP_RIGHT; // UP if (y != 0) { map[x][y].links[0] = &map[x][y-1]; } // RIGHT map[x][y].links[1] = &map[x+1][y]; break; case 'J': map[x][y].type = UP_LEFT; // UP if (y != 0) { map[x][y].links[0] = &map[x][y-1]; } // LEFT if (x != 0) { map[x][y].links[1] = &map[x-1][y]; } break; case '7': map[x][y].type = DOWN_LEFT; // DOWN map[x][y].links[0] = &map[x][y+1]; // LEFT if (x != 0) { map[x][y].links[1] = &map[x-1][y]; } break; case 'F': map[x][y].type = DOWN_RIGHT; // DOWN map[x][y].links[0] = &map[x][y+1]; // RIGHT map[x][y].links[1] = &map[x+1][y]; break; case 'S': map[x][y].type = START; break; } p++; x++; } y++; memset(buf, 0, MAX_MAP_SIZE); p = buf; } } // Find start tile_t *start, *curr, *prev; int found = 0; for (int i = 0; i < y; i++) { for (int j = 0; j < x; j++) { if (map[j][i].type == START) { start = &map[j][i]; curr = start; found = 1; int link_num = 0; // Connect up start tile // UP if (i != 0) { for (int k = 0; k < 2; k++) { if (map[j][i-1].links[k] == start) { start->links[link_num] = &map[j][i-1]; link_num++; break; } } } // DOWN for (int k = 0; k < 2; k++) { if (map[j][i+1].links[k] == start) { start->links[link_num] = &map[j][i+1]; link_num++; break; } } // LEFT if (j != 0) { for (int k = 0; k < 2; k++) { if (map[j-1][i].links[k] == start) { start->links[link_num] = &map[j-1][i]; link_num++; break; } } } // RIGHT for (int k = 0; k < 2; k++) { if (map[j+1][i].links[k] == start) { start->links[link_num] = &map[j+1][i]; link_num++; break; } } // Assign the correct type to the start tile, needed for part2 if (start->links[0] == &map[j][i-1] && start->links[1] == &map[j][i+1]) { start->type = UP_DOWN; } if (start->links[0] == &map[j][i-1] && start->links[1] == &map[j+1][i]) { start->type = UP_RIGHT; } if (start->links[0] == &map[j][i-1] && start->links[1] == &map[j-1][i]) { start->type = UP_LEFT; } if (start->links[0] == &map[j-1][i] && start->links[1] == &map[j+1][i]) { start->type = LEFT_RIGHT; } if (start->links[0] == &map[j][i+1] && start->links[1] == &map[j-1][i]) { start->type = DOWN_LEFT; } if (start->links[0] == &map[j][i+1] && start->links[1] == &map[j+1][i]) { start->type = DOWN_RIGHT; } break; } } if (found) { break; } } // Count to loop length unsigned long loop_length = 0; curr = start->links[0]; prev = start; start->part_of_loop = 1; while (curr != start) { curr->part_of_loop = 1; loop_length++; for (int i = 0; i < 2; i++) { if (prev != curr->links[i]) { prev = curr; curr = curr->links[i]; break; } } } unsigned long max_distance = loop_length % 2 ? loop_length / 2 + 1 : loop_length / 2; printf("%lu\n", max_distance); unsigned long inside_tile_count = 0; for (int i = 0; i < y; i++) { for (int j = 0; j < x; j++) { if (map[j][i].part_of_loop) { continue; } // Start going in a specific direction. (in this case right) // If we are inside the pipes we will cross the pipe an odd number of times int crosses = 0; // If we entered a pipe through F or L we have to keep track whether we cross the pipe when leaving int entry = 0; for (int k = 1; k < x - j; k++) { // We only care about pipes that are part of the loop if (!map[j+k][i].part_of_loop) { continue; } // If we are 'inside a pipe' we are no crossing it tile_type_t tile_type = map[j+k][i].type; if (tile_type == LEFT_RIGHT) { continue; } // Entering the loop. We are not crossing it yet, it depends on the exit tile if (tile_type == DOWN_RIGHT || tile_type == UP_RIGHT) { if (tile_type == DOWN_RIGHT) { entry = 1; } else { entry = 2; } continue; } // Vertical pipe, we are crossing the loop if (tile_type == UP_DOWN) { crosses += 1; entry = 0; continue; } // Exiting loop, check whether we crossed if (tile_type == DOWN_LEFT || tile_type == UP_LEFT) { if ((tile_type == DOWN_LEFT && entry == 2) || (tile_type == UP_LEFT && entry == 1)) { crosses += 1; } entry = 0; continue; } } if (crosses % 2) { inside_tile_count++; } } } printf("%lu\n", inside_tile_count); free(buf); }