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.
 
 
 

174 lines
4.1 KiB

#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#define ANSI_COLOR_RED "\x1b[31m"
#define ANSI_COLOR_RESET "\x1b[0m"
typedef struct {
unsigned int value;
bool marked;
} Cell;
typedef struct {
Cell cells[5][5];
} Grid;
unsigned int getEmptyLines(FILE *fp){
char line[500];
unsigned int emptyLines = 0;
while (!feof (fp)){
fgets(line, 500, fp);
//Length of 1 because it's a new line character only
if ( strlen(line) == 1 ) emptyLines ++;
}
return emptyLines;
}
//fp should be pointing to the start of the file as rounds are the first line
unsigned int countRounds(FILE *fp){
unsigned int rounds=0;
char ch = fgetc(fp);
while ( ch != EOF ){
switch (ch){
case ',':
rounds++;
break;
case '\n':
rounds++;
return rounds;
break;
}
ch = fgetc(fp);
}
return rounds;
}
void printGrid(Grid *grid){
for ( unsigned int row = 0; row < 5; row++ ){
for ( unsigned int col = 0; col < 5; col++ ){
if ( grid->cells[row][col].marked ) printf(ANSI_COLOR_RED);
printf("%3i", grid->cells[row][col].value);
if ( grid->cells[row][col].marked ) printf(ANSI_COLOR_RESET);
}
printf("\n");
}
}
void printAllGrids(Grid grids[], unsigned int no){
for( unsigned int i = 0; i<no; i++ ){
printf("Grid %i\n", i);
printGrid(&grids[i]);
printf("\n");
}
}
unsigned int sumUnmarked(Grid *grid){
unsigned int sum = 0;
for ( unsigned int row = 0; row < 5; row++ ){
for ( unsigned int col = 0; col < 5; col++ ){
if ( !grid->cells[row][col].marked ) sum += grid->cells[row][col].value;
}
}
return sum;
}
int main( int argc, char *argv[] ){
if( argc == 2 ) {
FILE *fp=fopen(argv[1], "r");
//The number of empty linse is the same as the number of grids
unsigned int gridCount = getEmptyLines(fp);
rewind(fp);
Grid grids[gridCount];
unsigned int rounds = countRounds(fp);
int draws[rounds];
memset( &draws, 0, rounds*sizeof(int) );
rewind(fp);
char ch;
for ( unsigned int i = 0; i < rounds; i++ ){
fscanf(fp, "%i%c,", &draws[i], &ch);
}
// Put all the numbers into the grid array
unsigned int no;
unsigned int grid = 0, row = 0, col = 0;
while ( !feof(fp) && fscanf(fp, "%i", &no) ){
grids[grid].cells[row][col].value = no;
grids[grid].cells[row][col].marked = false;
col = (col + 1) % 5;
if ( col == 0 ) row = (row + 1) % 5;
if ( col == 0 && row == 0 ) grid++;
}
//Start playing the game
bool bingo=false;
for (unsigned int round = 0; round < rounds && !bingo; round++){
for( unsigned int grid = 0; grid < gridCount && !bingo; grid++ ){
for( unsigned int row = 0; row < 5 && !bingo; row++ ){
for( unsigned int col = 0; col < 5 && !bingo; col++ ){
if ( grids[grid].cells[row][col].value == draws[round] ){
grids[grid].cells[row][col].marked = true;
//If we are above round 4, it's possible to have won
if ( round > 4 ){
bool maybebingorow=true;
bool maybebingocol=true;
// As soon as neither row or column is bingo, stop cheking
for (unsigned int i = 0; ( maybebingocol || maybebingorow ) && i < 5; i++){
// Go through the row and column for the matched number
// As soon as we find one in the row or column that isn't marked, we know that won't be bingo
if ( !grids[grid].cells[row][i].marked ) maybebingorow = false;
if ( !grids[grid].cells[i][col].marked ) maybebingocol = false;
}
//If we get here and maybebingocol or maybebingorow is true, we have bingo
if ( maybebingorow || maybebingocol ){
bingo=true;
unsigned int sum = sumUnmarked( &grids[grid] );
printf("Bingo!!\n");
printf("Round: %i\n", round);
printf("Grid: %i\n", grid);
printf("Unmarked Sum: %i\n", sum);
printf("Last Called: %i\n", draws[round]);
printf("Answer: %i\n", sum * draws[round]);
printf("\n");
printGrid(&grids[grid]);
}
}
}
}
}
}
//No point checking before round 5
}
fclose(fp);
return 0;
} else {
printf("You need to provide a file\n");
return 1;
}
}