#include #include #include #define DEFAULT_FILE "input.txt" #define STRBUF_LEN 200 #define NUM_CARDS 202 #define WINNING_NUM_SIZE 10 #define HOLDING_NUM_SIZE 25 #define ISDIGIT(X) (X >= '0' && X <= '9') void parse_nums(char *str, uint8_t *nums, uint8_t len) { uint8_t i = 0; uint8_t digit_idx = 0; char c; uint8_t num = 0; for (i = 0; i < len; i++) { num = 0; digit_idx = (i * 3); c = str[digit_idx]; if (ISDIGIT(c)) num = (c - '0') * 10; num += str[digit_idx + 1] - '0'; nums[i] = num; } } void parse_line(char *str, uint8_t *winning_nums, uint8_t *holding_nums) { while (*str != ':') str++; str += 2; parse_nums(str, winning_nums, WINNING_NUM_SIZE); while (*str != '|') str++; str += 2; parse_nums(str, holding_nums, HOLDING_NUM_SIZE); } bool num_in_set(uint8_t num, uint8_t *set, uint8_t len) { uint8_t i = 0; for (i = 0; i < len; i++) { if (num == set[i]) return true; } return false; } uint32_t calculate_points(uint8_t *winning_nums, uint8_t *holding_nums) { uint32_t points = 0; uint8_t i = 0; for (i = 0; i < HOLDING_NUM_SIZE; i++) { if (num_in_set(holding_nums[i], winning_nums, WINNING_NUM_SIZE)) points++; } return points; } int main(int argc, char **argv) { // Get filename as an argument, defaults to "input.txt" char *path = (argc > 1) ? argv[1] : DEFAULT_FILE; if (!path) { printf("Requires input file.\n"); return 1; } FILE *file = fopen(path, "r"); if (!file) { printf("Could not find file."); return 1; } char strbuf[STRBUF_LEN] = {0}; uint8_t winning_nums[WINNING_NUM_SIZE] = {0}; uint8_t holding_nums[HOLDING_NUM_SIZE] = {0}; uint64_t points = 0; uint64_t card_copies[NUM_CARDS] = { [0 ... NUM_CARDS-1] = 1 }; uint8_t i = 0; uint8_t copyidx = 0; uint8_t cardidx = 0; for (cardidx = 0; cardidx < NUM_CARDS; cardidx++) { fgets(strbuf, STRBUF_LEN, file); if (strbuf[0] == '\n') break; parse_line(strbuf, winning_nums, holding_nums); points = calculate_points(winning_nums, holding_nums); for (i = 0; i < points; i++) { // Add copy of card for every point if (cardidx + i < NUM_CARDS) card_copies[cardidx + i + 1] = card_copies[cardidx + i + 1] + card_copies[cardidx]; else break; } } points = 0; for (i = 0; i < NUM_CARDS; i++) { points += card_copies[i]; } printf("Total cards: %d", points); return 0; }