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