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.
159 lines
3.8 KiB
159 lines
3.8 KiB
#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; |
|
} |
|
}
|
|
|