You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
3.8 KiB
160 lines
3.8 KiB
3 years ago
|
#include <stdio.h>
|
||
|
#include <stdbool.h>
|
||
|
#include <string.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
#define ANSI_COLOR_RED "\x1b[31m"
|
||
|
#define ANSI_COLOR_YELLOW "\x1b[33m"
|
||
|
#define ANSI_COLOR_RESET "\x1b[0m"
|
||
|
|
||
|
#define MAX(a, b) ((a) < (b) ? (b) : (a))
|
||
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||
|
|
||
|
typedef struct Square Square;
|
||
|
|
||
|
struct Square{
|
||
|
unsigned int risk;
|
||
|
Square *previous;
|
||
|
unsigned int distanceFromStart;
|
||
|
Square *up;
|
||
|
Square *down;
|
||
|
Square *left;
|
||
|
Square *right;
|
||
|
bool onShortestPath;
|
||
|
bool used;
|
||
|
};
|
||
|
|
||
|
|
||
|
int countRows(FILE *fp){
|
||
|
unsigned int lines=0;
|
||
|
|
||
|
while (EOF != (fscanf(fp, "%*[^\n]"), fscanf(fp,"%*c")))
|
||
|
++lines;
|
||
|
return lines;
|
||
|
}
|
||
|
|
||
|
int countCols(FILE *fp){
|
||
|
unsigned int lineLength=0;
|
||
|
char ch = fgetc(fp);
|
||
|
while ( ch != '\n' ){
|
||
|
lineLength++;
|
||
|
ch = fgetc(fp);
|
||
|
}
|
||
|
return lineLength;
|
||
|
}
|
||
|
|
||
|
void printGrid( unsigned int cols, unsigned int rows, Square **grid){
|
||
|
for ( unsigned int row = 0; row < rows; row++ ){
|
||
|
for ( unsigned int col = 0; col < cols; col++ ){
|
||
|
if ( grid[col][row].onShortestPath ) printf(ANSI_COLOR_RED);
|
||
|
printf("%i ", grid[col][row].risk);
|
||
|
if ( grid[col][row].onShortestPath ) printf(ANSI_COLOR_RESET);
|
||
|
}
|
||
|
printf("\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void maybeUpdate(Square *current, Square *adjacent){
|
||
|
if ( adjacent == NULL ) return ;
|
||
|
if ( current->distanceFromStart + adjacent->risk < adjacent->distanceFromStart ){
|
||
|
adjacent->distanceFromStart = current->distanceFromStart + adjacent->risk;
|
||
|
adjacent->previous = current;
|
||
|
}
|
||
|
}
|
||
|
void markAdjacent(Square *current){
|
||
|
unsigned int currentDistance = current->distanceFromStart;
|
||
|
maybeUpdate(current, current->up);
|
||
|
maybeUpdate(current, current->down);
|
||
|
maybeUpdate(current, current->left);
|
||
|
maybeUpdate(current, current->right);
|
||
|
}
|
||
|
|
||
|
Square* getLowestEndScoredSquare( Square**grid, unsigned int cols, unsigned int rows ){
|
||
|
Square *lowest = &grid[cols][rows];
|
||
|
for ( unsigned int row = 0; row < rows; row++ ){
|
||
|
for ( unsigned int col = 0; col < cols; col++ ){
|
||
|
//printf("%i\n",lowest->distanceFromStart);
|
||
|
if ( (!grid[col][row].used) && (grid[col][row].distanceFromStart < lowest->distanceFromStart) ){
|
||
|
printf("col: %i row: %i\n",col,row);
|
||
|
lowest = &grid[col][row];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return lowest;
|
||
|
}
|
||
|
|
||
|
|
||
|
int main( int argc, char *argv[] ){
|
||
|
if( argc == 2 ) {
|
||
|
|
||
|
|
||
|
FILE *fp=fopen(argv[1], "r");
|
||
|
|
||
|
unsigned int cols=countCols(fp);
|
||
|
rewind(fp);
|
||
|
unsigned int rows=countRows(fp);
|
||
|
rewind(fp);
|
||
|
|
||
|
Square **grid=(Square**)malloc( cols * sizeof(Square *));
|
||
|
for(unsigned int i=0; i<=rows;i++) {
|
||
|
grid[i]=(Square*)malloc( (rows) *sizeof(Square));
|
||
|
memset(grid[i], 0, sizeof(Square) * ( rows ));
|
||
|
}
|
||
|
|
||
|
char ch;
|
||
|
unsigned int row=0, col=0;
|
||
|
while ( !feof(fp) && fscanf(fp, "%c", &ch) ){
|
||
|
if ( ch == '\n' ){
|
||
|
col = 0;
|
||
|
row++;
|
||
|
continue;
|
||
|
}
|
||
|
grid[col][row].risk = atoi(&ch);
|
||
|
grid[col][row].distanceFromStart = ~0;
|
||
|
grid[col][row].up = ( row > 0 ) ? &grid[col][row-1] : NULL;
|
||
|
grid[col][row].down = ( row < rows - 1 ) ? &grid[col][row+1] : NULL;
|
||
|
grid[col][row].left = ( col > 0 ) ? &grid[col-1][row] : NULL;
|
||
|
grid[col][row].right = ( col < cols - 1 ) ? &grid[col+1][row] : NULL;
|
||
|
grid[col][row].onShortestPath = false;
|
||
|
grid[col][row].used = false;
|
||
|
col++;
|
||
|
}
|
||
|
|
||
|
|
||
|
Square *current = &grid[0][0];
|
||
|
unsigned int i = 0;
|
||
|
while (true){
|
||
|
markAdjacent(current);
|
||
|
current->used = true;
|
||
|
if (current == &grid[cols-1][rows-1] ) break;
|
||
|
current = getLowestEndScoredSquare(grid, cols, rows);
|
||
|
i++;
|
||
|
printf("---\n");
|
||
|
}
|
||
|
|
||
|
unsigned int total = 0;
|
||
|
|
||
|
while ( true ){
|
||
|
current->onShortestPath = true;
|
||
|
total += current->risk;
|
||
|
if ( current != &grid[0][0] )
|
||
|
current = current->previous;
|
||
|
else
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
printGrid(cols, rows, grid);
|
||
|
//grid[0][0].distanceFromStart = 0;
|
||
|
printf("Total risk: %i\n", total - grid[0][0].risk);
|
||
|
//markAdjacent(grid, 0, 0);
|
||
|
|
||
|
|
||
|
fclose(fp);
|
||
|
return 0;
|
||
|
} else {
|
||
|
printf("You need to provide a file\n");
|
||
|
return 1;
|
||
|
}
|
||
|
}
|