143 lines
3.5 KiB
C
143 lines
3.5 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#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;
|
|
}
|