My solutions to the advent of code
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

#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;
}
}