10b.c (3405B)
1 #include <stdio.h> 2 3 #define N 1000 4 #define set(i, j, c) if (newmap[i][j] == '.') newmap[i][j] = c; 5 6 typedef enum { EAST, SOUTH, WEST, NORTH } direction_t; 7 8 char map[N+2][N+2], newmap[N+2][N+2]; 9 int n, si, sj, count[26] = {0}; 10 direction_t sdir; 11 12 void printmap(char m[][N+2]) { 13 for (int i = 1; i < n; i++) { 14 for (int j = 1; m[i][j] != 'B'; j++) 15 printf("%c", m[i][j]); 16 printf("\n"); 17 } 18 } 19 20 void color_rl(direction_t dir, int i, int j) { 21 switch (dir) { 22 case EAST: 23 set(i-1, j, 'L'); 24 set(i+1, j, 'R'); 25 break; 26 case SOUTH: 27 set(i, j+1, 'L'); 28 set(i, j-1, 'R'); 29 break; 30 case WEST: 31 set(i-1, j, 'R'); 32 set(i+1, j, 'L'); 33 break; 34 case NORTH: 35 set(i, j+1, 'R'); 36 set(i, j-1, 'L'); 37 break; 38 default: 39 break; 40 } 41 } 42 43 direction_t firstdir(int i, int j) { 44 if (map[i][j+1] == '7' || map[i][j+1] == '-' || map[i][j+1] == 'J') 45 return EAST; 46 if (map[i+1][j] == 'L' || map[i+1][j] == '|' || map[i+1][j] == 'J') 47 return SOUTH; 48 return WEST; 49 } 50 51 void advance(int *i, int *j, direction_t dir) { 52 if (dir == EAST) { (*j)++; } 53 else if (dir == SOUTH) { (*i)++; } 54 else if (dir == WEST) { (*j)--; } 55 else (*i)--; 56 } 57 58 direction_t newdir(int i, int j, direction_t dir) { 59 switch (map[i][j]) { 60 case '|': 61 case '-': 62 return dir; 63 case '7': 64 if (dir == EAST) return SOUTH; 65 if (dir == NORTH) return WEST; 66 case 'F': 67 if (dir == WEST) return SOUTH; 68 if (dir == NORTH) return EAST; 69 case 'J': 70 if (dir == EAST) return NORTH; 71 if (dir == SOUTH) return WEST; 72 case 'L': 73 if (dir == WEST) return NORTH; 74 if (dir == SOUTH) return EAST; 75 default: 76 printf("Error: dead path at (%d, %d)\n", i, j); 77 exit(1); 78 } 79 return EAST; 80 } 81 82 void walk_and_color_rl(char c) { 83 int i = si, j = sj; 84 direction_t dir = sdir; 85 86 newmap[i][j] = c; 87 color_rl(dir, i, j); 88 advance(&i, &j, dir); 89 for (; map[i][j] != 'S'; advance(&i, &j, dir)) { 90 newmap[i][j] = c; 91 color_rl(dir, i, j); 92 dir = newdir(i, j, dir); 93 color_rl(dir, i, j); 94 } 95 color_rl(dir, i, j); 96 } 97 98 void fill(int i, int j, char c) { 99 if (newmap[i][j] != '.' && newmap[i][j] != 'R' && newmap[i][j] != 'L') 100 return; 101 102 newmap[i][j] = c; 103 count[c-'a']++; 104 fill(i, j+1, c); 105 fill(i, j-1, c); 106 fill(i+1, j, c); 107 fill(i-1, j, c); 108 } 109 110 int main() { 111 /* Get input */ 112 for (n = 1; fgets(&map[n][1], N, stdin) != NULL; n++) ; 113 114 /* Add borders, copy to newmap */ 115 for (int i = 0; i < N+2; i++) { 116 for (int j = 0; j < N+2; j++) { 117 newmap[i][j] = map[i][j]; 118 if (map[i][j] == 0 || map[i][j] == '\n') 119 newmap[i][j] = map[i][j] = 'B'; 120 } 121 } 122 123 /* Find S and set the initial direction */ 124 for (si = 1; si < n; si++) 125 for (sj = 1; map[si][sj] != 'B'; sj++) 126 if (map[si][sj] == 'S') 127 goto found_s; 128 129 found_s: 130 /* Set the initial direction and walk the path mark it with X */ 131 sdir = firstdir(si, sj); 132 walk_and_color_rl('X'); 133 134 /* Replace the unnecessary pipe symbols with dots */ 135 for (int i = 1; i < N; i++) 136 for (int j = 1; map[i][j] != 'B'; j++) 137 if (newmap[i][j] != 'X') 138 newmap[i][j] = '.'; 139 140 /* Walk again the path and mark adjacent dots left and right */ 141 walk_and_color_rl('Y'); 142 143 /* Mark the remaining dots left and right */ 144 for (int i = 1; i < n; i++) 145 for (int j = 1; newmap[i][j] != 'B'; j++) 146 if (newmap[i][j] == 'R' || newmap[i][j] == 'L') 147 fill(i, j, newmap[i][j] + 'a' - 'A'); 148 149 printmap(newmap); 150 printf("r: %d\nl: %d\n", count['r'-'a'], count['l'-'a']); 151 printf("Check with the map printed above which one is 'inside'\n"); 152 return 0; 153 }