#include #include #include #include #include #include #include #define RESET "\033[0m" #define RED "\033[31m" #define DEBUG #define INPUT_FILE ("../input_test.txt") #define MAX_NUMBERS_DRAWN (1024) #define MAX_BOARDS (256) /* Think of the win_conditions array as this table of win conditions WIN CONDITIONS * x x x x x * x x x x x * x x x x x * x x x x x * * x x x x x * x x x x x * x x x x x * x x x x x * * x x x x x * x x x x x * x x x x x * x x x x x * * x x x x x * x x x x x * x x x x x * x x x x x * * x x x x x * x x x x x * x x x x x * x x x x x * * * * * * x x x x x x x x x x x x x x x x x x x x x x x x x * * * * * x x x x x x x x x x x x x x x x x x x x x x x x x * * * * * x x x x x x x x x x x x x x x x x x x x x x x x x * * * * * x x x x x x x x x x x x x x x x x x x x x x x x x * * * * * * x x x x x x x x * x * x x x x x x * x x x * x x x x * x x x x x * x x * x x x x x x x * * x x x x */ const uint32_t win_conditions[12] = { 0b00000000000100001000010000100001, 0b00000000001000010000100001000010, 0b00000000010000100001000010000100, 0b00000000100001000010000100001000, 0b00000001000010000100001000010000, 0b00000000000000000000000000011111, 0b00000000000000000000001111100000, 0b00000000000000000111110000000000, 0b00000000000011111000000000000000, 0b00000001111100000000000000000000, 0b00000001000001000001000001000001, 0b00000000000100010001000100010000, }; typedef struct board_t { uint8_t matrix[5][5]; // idk what to call this // its just a u32, if the number in a slot x has been drawn, // then a 1 will be in that bit position inside of this number // example: slot[3][4] = (3 * 5) + 4 = 19, if this slot has been drawn, // bit position 19 will be a 1 uint32_t output; uint8_t most_recently_drawn; }board_t; bool bingo_board_win_check(const board_t* board); int bingo_board_compute_answer(const board_t* board); bool bingo_add_new_entry(board_t* board, uint8_t num); void print_bingo_board(const board_t* board); int main(void) { int p1_answer = 0; board_t bingo_bank[MAX_BOARDS]; uint16_t bingo_board_count = 0; uint8_t bingo_drawn_numbers[MAX_NUMBERS_DRAWN]; uint16_t bingo_drawn_numbers_ct = 0; memset(bingo_bank, 0, sizeof(board_t) * MAX_BOARDS); FILE* fp = fopen(INPUT_FILE, "r"); if(fp == NULL) { printf("Failed to open input file for reading...\n"); exit(-1); } size_t len; ssize_t rc; char* line = NULL; rc = getline(&line, &len, fp); const char* delim = ", \r\n"; char* tok = strtok(line, delim); while(tok != NULL) { bingo_drawn_numbers[bingo_drawn_numbers_ct++] = strtoul(tok, NULL, 10); tok = strtok(NULL, delim); } while(bingo_board_count < MAX_BOARDS && fp != NULL) { // continue to numbers.... char c = '\0'; while(!isdigit(c) && !feof(fp)) { c = fgetc(fp); } if(feof(fp)) { break; } fseek(fp, -1, SEEK_CUR); for(int ind = 0; ind < 5; ind++) { rc = getline(&line, &len, fp); if(rc < 0) { printf("some error while parsing"); exit(-1); } printf("Reading in this line: %s", line); sscanf(line, "%2" SCNu8 " " "%2" SCNu8 " " "%2" SCNu8 " " "%2" SCNu8 " " "%2" SCNu8 " ", &bingo_bank[bingo_board_count].matrix[ind][0], &bingo_bank[bingo_board_count].matrix[ind][1], &bingo_bank[bingo_board_count].matrix[ind][2], &bingo_bank[bingo_board_count].matrix[ind][3], &bingo_bank[bingo_board_count].matrix[ind][4]); } printf("done reading lines\n\n"); bingo_board_count++; } #ifdef DEBUG for(int ind = 0; ind < bingo_board_count; ind++) { print_bingo_board(&bingo_bank[ind]); } #endif for(int ind = 0; ind < bingo_drawn_numbers_ct; ind++) { printf("... drawing number ... Number #%d!\n", bingo_drawn_numbers[ind]); for(int board = 0; board < bingo_board_count; board++) { if(bingo_add_new_entry(&bingo_bank[board], bingo_drawn_numbers[ind])) { p1_answer = bingo_board_compute_answer(&bingo_bank[board]); #ifdef DEBUG print_bingo_board(&bingo_bank[board]); #endif break; } #ifdef DEBUG print_bingo_board(&bingo_bank[board]); #endif } if(p1_answer != 0) { break; } } printf("Answer for part 1: %d\n", p1_answer); return 0; } // returns bool bingo_add_new_entry(board_t* board, uint8_t num) { for(int ind = 0; ind < 5; ind++) { for(int jind = 0; jind < 5; jind++) { if(board->matrix[ind][jind] == num) { board->output |= (1 << (ind * 5 + jind)); board->most_recently_drawn = num; return bingo_board_win_check(board); } } } return false; } bool bingo_board_win_check(const board_t* board) { for(int wc = 0; wc < 12; wc++) { // found a winner check if((board->output & win_conditions[wc]) == win_conditions[wc]) { return true; } } return false; } int bingo_board_compute_answer(const board_t* board) { int result = 0; for(int ind = 0; ind < 5; ind++) { for(int jind = 0; jind < 5; jind++) { if(!(board->output & (1 << ((ind * 5) + jind)))) { result += board->matrix[ind][jind]; } } } result *= board->most_recently_drawn; return result; } void print_bingo_board(const board_t* board) { printf("\n"); for(int ind = 0; ind < 5; ind++) { for(int jind = 0; jind < 5; jind++) { if(board->output & (1 << ((ind * 5) + jind))) { printf(RED "%2d " RESET, board->matrix[ind][jind]); } else { printf("%2d ", board->matrix[ind][jind]); } } printf("\r\n"); } }