#include #include #define MAX_DIMENSION 1024 #define MAX_MOVES 1024*1024 typedef enum tile { EMPTY, WALL, BOX, ROBOT } tile_t; int try_move(tile_t **map, int rows, int columns, int x, int y, int dir[2]); int main() { char c; tile_t **map = calloc(MAX_DIMENSION, sizeof(map[0])); int rows = 0, columns, i = 0; map[0] = calloc(MAX_DIMENSION, sizeof(map[0][0])); int reading_map = 1; int (*moves)[2] = calloc(MAX_MOVES, sizeof(moves[0])); int move_count = 0; int robot_pos[2]; while ((c = getchar()) != EOF) { if (reading_map) { if (i == 0 && c == '\n') { reading_map = 0; continue; } switch (c) { case '.': map[rows][i] = EMPTY; break; case '#': map[rows][i] = WALL; break; case 'O': map[rows][i] = BOX; break; case '@': map[rows][i] = ROBOT; robot_pos[0] = rows; robot_pos[1] = i; break; } i++; if (c != '\n') { continue; } columns = i - 1; i = 0; rows++; map[rows] = calloc(MAX_DIMENSION, sizeof(map[0][0])); } else { switch(c) { case '>': moves[move_count][0] = 0; moves[move_count][1] = 1; move_count++; break; case '<': moves[move_count][0] = 0; moves[move_count][1] = -1; move_count++; break; case 'v': moves[move_count][0] = 1; moves[move_count][1] = 0; move_count++; break; case '^': moves[move_count][0] = -1; moves[move_count][1] = 0; move_count++; break; } } } for (i = 0; i < move_count; i++) { if (try_move(map, rows, columns, robot_pos[0], robot_pos[1], moves[i])) { robot_pos[0] += moves[i][0]; robot_pos[1] += moves[i][1]; } } int sum = 0; for (i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { if (map[i][j] == BOX) { sum += 100 * i + j; } } } for (i = 0; i < rows + 1; i++) { free(map[i]); } free(map); free(moves); printf("%i\n", sum); } int try_move(tile_t **map, int rows, int columns, int x, int y, int dir[2]) { // Walls cannot move if (map[x][y] == WALL) { return 0; } // Empty space can be filled if (map[x][y] == EMPTY) { return 1; } // A box/robot can move if the next tile is movable int next_x = x + dir[0]; int next_y = y + dir[1]; // Cannot move out of the map although it should not be possible to reach this if (next_x < 0 || next_y < 0 || next_x >= rows || next_y >= columns) { return 0; } int success = try_move(map, rows, columns, next_x, next_y, dir); // If successfully moved, update map if (success) { map[next_x][next_y] = map[x][y]; map[x][y] = EMPTY; } return success; }