#define _GNU_SOURCE #include #include #include #define DIMENSION_MAX 512 #define abs(a) ((a) < 0 ? (-(a)) : (a)) typedef enum { EMPTY, OBSTRUCTION } tile_t; const int directions[][2] = { {0, 1}, {1, 0}, {0, -1}, {-1, 0}, }; #define directions_len (sizeof(directions) / sizeof(directions[0])) int update(int pos[2], int dir[2], int* dir_idx, tile_t **map, int rows, int cols, int** visited, int* count); void next_dir(int dir[2], int *dir_idx); int main() { char c; tile_t **map = calloc(DIMENSION_MAX, sizeof(map[0])); int rows = 0, columns = 0, i = 0; map[rows] = calloc(DIMENSION_MAX, sizeof(map[0][0])); int pos[2] = { 0 }; int dir[2] = { 0 }; int dir_idx = 0; int mypos[2] = { 0 }; int mydir[2] = { 0 }; int mydir_idx = 0; while ((c = getchar()) != EOF) { switch (c) { case '.': map[rows][i] = EMPTY; break; case '#': map[rows][i] = OBSTRUCTION; break; case '>': mypos[0] = rows; mypos[1] = i; mydir[0] = 0; mydir[1] = 1; mydir_idx = 0; break; case '^': pos[0] = rows; pos[1] = i; dir[0] = -1; dir[1] = 0; dir_idx = 3; break; default: break; } i++; if (c != '\n') { continue; } columns = i - 1; rows++; map[rows] = calloc(DIMENSION_MAX, sizeof(map[0][0])); i = 0; } int **visited = calloc(rows, sizeof(visited[0])); for (i = 0; i < columns; i++) { visited[i] = calloc(columns, sizeof(visited[0][0])); } int start[5] = {pos[0], pos[1], dir[0], dir[1], dir_idx}; int move_count = 0; while (update(pos, dir, &dir_idx, map, rows, columns, visited, &move_count)); int count = 0; for (i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { count += visited[i][j]; } } int count2 = 0; for (i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { if (map[i][j] == EMPTY && visited[i][j] && !(i == start[0] && j == start[1])) { int **tmp = calloc(rows, sizeof(tmp[0])); for (int k = 0; k < rows; k++) { tmp[k] = calloc(columns, sizeof(tmp[0][0])); } pos[0] = start[0]; pos[1] = start[1]; dir[0] = start[2]; dir[1] = start[3]; dir_idx = start[4]; move_count = 0; map[i][j] = OBSTRUCTION; int result; while((result = update(pos, dir, &dir_idx, map, rows, columns, tmp, &move_count)) == 1); if (result == 2) { count2++; } map[i][j] = EMPTY; for (int k = 0; k < rows; k++) { free(tmp[k]); } free(tmp); } } } for (i = 0; i < rows + 1; i++) { free(map[i]); } free(map); for (i = 0; i < columns; i++) { free(visited[i]); } free(visited); printf("%i\n", count); printf("%i\n", count2); } int update(int pos[2], int dir[2], int* dir_idx, tile_t **map, int rows, int cols, int** visited, int *count) { int y = pos[0] + dir[0]; int x = pos[1] + dir[1]; // Exiting map if (y < 0 || x < 0 || y >= rows || x >= cols) { return 0; } switch (map[y][x]) { case OBSTRUCTION: next_dir(dir, dir_idx); break; case EMPTY: pos[0] = y; pos[1] = x; visited[y][x] = 1; break; } (*count)++; // Looping if (*count > cols * rows * 4) { return 2; } return 1; } void next_dir(int dir[2], int *dir_idx) { (*dir_idx)++; if (*dir_idx == directions_len) { *dir_idx = 0; } dir[0] = directions[*dir_idx][0]; dir[1] = directions[*dir_idx][1]; }