#include #include #include #include "puzzle_input.h" #include "day.h" #define BINGO_BOARD_SIZE 5 #define MAX_BINGO_BOARDS 101 #define MAX_DRAWS 100 typedef struct { uint8_t board[BINGO_BOARD_SIZE][BINGO_BOARD_SIZE]; uint8_t matches[BINGO_BOARD_SIZE][BINGO_BOARD_SIZE]; uint8_t won; } bingo_board_t; typedef struct { uint8_t num_boards; uint8_t num_draws; bingo_board_t boards[MAX_BINGO_BOARDS]; uint8_t draws[MAX_DRAWS]; } bingo_input_t; parse_ret_t parse_bingo_input(char * buffer, void * data, uint16_t index) { bingo_input_t * bingo_data = (bingo_input_t *)data; char * tok; parse_ret_t res; if (index == 0) { uint8_t draw_ndx = 0; tok = strtok(buffer, ","); while (tok != NULL) { int64_t draw_val; res = parse_long(tok, &draw_val, 10); if (res != PARSER_OK) { return res; } bingo_data->draws[draw_ndx] = (uint8_t)draw_val; draw_ndx++; tok = strtok(NULL, ","); } bingo_data->num_draws = draw_ndx+1; } else { index--; // skip the draws line tok = strtok(buffer, " "); for (int row = 0; row < BINGO_BOARD_SIZE; row++) { for (int col = 0; col < BINGO_BOARD_SIZE; col++) { int64_t val; res = parse_long(tok, &val, 10); if (res != PARSER_OK) { return res; } bingo_data->boards[index].board[row][col] = (uint8_t)val; tok = strtok(NULL, " "); } } bingo_data->num_boards++; } return PARSER_OK; } bingo_input_t bingo_input_g = { .num_boards = 0, .num_draws = 0, .boards = {0}, }; uint32_t calc_score(bingo_board_t * board, uint8_t final_number) { uint32_t sum = 0; for (int row = 0; row < BINGO_BOARD_SIZE; row++) { for (int col = 0; col < BINGO_BOARD_SIZE; col++) { if (!board->matches[row][col]) { sum += board->board[row][col]; } } } return sum*final_number; } int day_4() { uint16_t len; uint8_t first_winner_found = 0; int32_t winner_count = 0; int32_t last_winner_ndx = -1; int32_t last_winner_number = -1; uint32_t score; parse_ret_t res = read_input_multi_line("../inputs/day_4.txt", (void *)&bingo_input_g, MAX_BINGO_BOARDS+1, "", parse_bingo_input, &len); if (res != PARSER_OK) { printf("Failed to parse input: %d", res); return -1; } for (int draw_ndx = 0; draw_ndx < bingo_input_g.num_draws; draw_ndx++) { uint16_t draw = bingo_input_g.draws[draw_ndx]; for (int board_ndx = 0; board_ndx < bingo_input_g.num_boards; board_ndx++) { uint8_t match_found = 0; bingo_board_t *board = &bingo_input_g.boards[board_ndx]; for (int row = 0; row < BINGO_BOARD_SIZE; row++) { for (int col = 0; col < BINGO_BOARD_SIZE; col++) { if (board->board[row][col] == draw) { board->matches[row][col] = 1; match_found = 1; } if (match_found) { break; } } } if (!board->won) { uint8_t won_flag = 0; for (int row = 0; row < BINGO_BOARD_SIZE; row++) { if (board->matches[row][0] && board->matches[row][1] && board->matches[row][2] && board->matches[row][3] && board->matches[row][4]) { if (!first_winner_found) { first_winner_found = 1; score = calc_score(board, draw); } winner_count++; board->won = 1; won_flag = 1; break; } } if (!won_flag) { for (int col = 0; col < BINGO_BOARD_SIZE; col++) { if (board->matches[0][col] && board->matches[1][col] && board->matches[2][col] && board->matches[3][col] && board->matches[4][col]) { if (!first_winner_found) { first_winner_found = 1; score = calc_score(board, draw); } board->won = 1; winner_count++; break; } } } if (winner_count == bingo_input_g.num_boards) { last_winner_ndx = board_ndx; last_winner_number = draw; break; } } } if (last_winner_ndx >= 0) { break; } } if (first_winner_found == 0) { printf("Something went wrong, no winner was found\n"); return -2; } printf("PART 1: The final score was %d\n", score); if (last_winner_ndx < 0) { printf("Something went wrong, no last winner was found\n"); return -3; } uint32_t last_score = calc_score(&bingo_input_g.boards[last_winner_ndx], last_winner_number); printf("PART 2: The final score of the last board was %d\n", last_score); return 0; }