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.
 
 
 

157 lines
3.3 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"
typedef struct Position {
int value;
bool marked;
bool lowpoint;
} Position;
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;
}
bool isMinimum(int rows, int cols, Position grid[rows][cols], int row, int col){
// Check above
if ( row > 0 && grid[row-1][col].value <= grid[row][col].value ) return false;
//check below
if ( row < rows-1 && grid[row+1][col].value <= grid[row][col].value ) return false;
// Check left
if ( col > 0 && grid[row][col-1].value <= grid[row][col].value ) return false;
//check below
if ( col < cols-1 && grid[row][col+1].value <= grid[row][col].value ) return false;
return true;
}
int cmp_asc_int(const void *a, const void *b) {
return *(int*)a > *(int*)b;
}
unsigned int basinSize(int rows, int cols, Position grid[rows][cols], int row, int col){
unsigned int ret = 0;
if ( grid[row][col].value == 9 ){
return 0;
}
ret++;
grid[row][col].marked = true;
//Check above
if ( row > 0 && ! grid[row-1][col].marked )
ret+=basinSize(rows, cols, grid, row-1, col);
//Check below
if ( row < rows-1 && ! grid[row+1][col].marked )
ret+=basinSize(rows, cols, grid, row+1, col);
// Check left
if ( col > 0 && ! grid[row][col-1].marked )
ret+=basinSize(rows, cols, grid, row, col-1);
//check right
if ( col < cols-1 && ! grid[row][col+1].marked )
ret+=basinSize(rows, cols, grid, row, col+1);
return ret;
}
void printGrid(int rows, int cols, Position grid[rows][cols]){
for ( unsigned int row = 0; row < rows; row++ ){
for ( unsigned int col = 0; col < cols; col++ ){
if ( grid[row][col].lowpoint ) printf(ANSI_COLOR_RED);
else if ( grid[row][col].marked ) printf(ANSI_COLOR_YELLOW);
printf("%i", grid[row][col].value );
if ( grid[row][col].marked ) printf(ANSI_COLOR_RESET);
}
printf("\n");
}
}
int main( int argc, char *argv[] ){
if( argc == 2 ) {
FILE *fp=fopen(argv[1], "r");
if ( fp == NULL ) {
return 1;
}
unsigned int rows=countRows(fp);
rewind(fp);
unsigned int cols=countCols(fp);
rewind(fp);
Position grid[rows][cols];
memset( &grid, 0, rows*cols*sizeof(Position) );
unsigned int risk=0, row=0, col=0;
unsigned int max[4] = {0};
for ( char ch = fgetc(fp); EOF != ch; ch=fgetc(fp)){
if ( ch == '\n' ){
row++;
col=0;
} else {
grid[row][col].value = atoi(&ch);
col++;
}
}
for ( unsigned int row = 0; row < rows; row++ ){
for ( unsigned int col = 0; col < cols; col++ ){
if ( isMinimum(rows, cols, grid, row, col) ){
risk+= grid[row][col].value+1;
grid[row][col].lowpoint = true;
max[0] = basinSize(rows, cols, grid, row, col);
qsort(max, 4, sizeof(unsigned int), cmp_asc_int);
}
}
}
unsigned int prouduct=1;
printf("The largest 3 basins are:\n");
for (unsigned int i = 1; i < 4; i++){
printf("* %i\n", max[i]);
prouduct *= max[i];
}
printf("\nProduct is %i\n", prouduct);
fclose(fp);
return 0;
} else {
printf("You need to provide a file\n");
return 1;
}
}