126 lines
3.1 KiB
C
126 lines
3.1 KiB
C
//
|
|
// Created by lennart on 12/6/23.
|
|
//
|
|
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
#include "input_handler.h"
|
|
|
|
typedef struct {
|
|
int countWinningNumbers;
|
|
int winningNumbers[10];
|
|
int countGivenNumbers;
|
|
int givenNumbers[25];
|
|
int copies;
|
|
} Card;
|
|
|
|
#define LIST_NAME CardList
|
|
#define LIST_PREFIX clist
|
|
#define ELEMENT_TYPE Card
|
|
#include "list.h"
|
|
|
|
CardList* load_cards(const char *file_name);
|
|
|
|
int main() {
|
|
CardList *cards = load_cards("day_4.txt");
|
|
|
|
// Part 1 - Iterate over given numbers and linearly check for matches
|
|
int sum = 0;
|
|
int sum2 = 0; // Part 2
|
|
for(int i = 0; i < cards->length; i++) {
|
|
Card card = cards->data[i];
|
|
int won = 0;
|
|
|
|
for(int j = 0; j < card.countGivenNumbers; j++) {
|
|
int given = card.givenNumbers[j];
|
|
|
|
for(int k = 0; k < card.countWinningNumbers; k++) {
|
|
if(card.winningNumbers[k] == given) {
|
|
won += 1;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
sum += (1 << won) >> 1;
|
|
// Part 2 - Begin (register copies won)
|
|
sum2 += card.copies;
|
|
for(int j = 1; j <= won && (i + j) < cards->length; j++) {
|
|
cards->data[i + j].copies += card.copies;
|
|
}
|
|
// Part 2 - End
|
|
}
|
|
printf("Result #1: %i\n", sum);
|
|
printf("Result #2: %i\n", sum2);
|
|
|
|
clist_free(cards);
|
|
}
|
|
|
|
CardList* load_cards(const char *file_name) {
|
|
FILE *f = fopen(file_name, "r");
|
|
if(f == NULL) {
|
|
printf("Error! Missing input file");
|
|
exit(1);
|
|
}
|
|
|
|
CardList *list = clist_create(16);
|
|
char* buffer = NULL;
|
|
int bufferLen = 0;
|
|
|
|
while(!feof(f)) {
|
|
char *line = read_line(f, &buffer, &bufferLen);
|
|
if(strlen(line) < strlen("Game 1: ")) {
|
|
continue;
|
|
}
|
|
|
|
line = &line[strlen("Game ")];
|
|
while(*line == ' ') line++;
|
|
int gameId = (int) strtol(line, &line, 10);
|
|
|
|
Card card;
|
|
card.countWinningNumbers = 0;
|
|
card.countGivenNumbers = 0;
|
|
card.copies = 1;
|
|
|
|
// Find the winning numbers
|
|
line += 2;
|
|
while(*line != '|') {
|
|
if(*line == 0) {
|
|
printf("Error! Unexpected end of line: %s", buffer);
|
|
exit(1);
|
|
}
|
|
if(!isdigit(*line)) {
|
|
line++;
|
|
continue;
|
|
}
|
|
if(card.countWinningNumbers >= 10) {
|
|
printf("Error! Given numbers out of bounds in: %s", buffer);
|
|
exit(1);
|
|
}
|
|
|
|
int num = (int) strtol(line, &line, 10);
|
|
card.winningNumbers[card.countWinningNumbers++] = num;
|
|
}
|
|
|
|
// Find the given numbers
|
|
line += 2;
|
|
while(*line != 0) {
|
|
if(card.countGivenNumbers >= 25) {
|
|
printf("Error! Given numbers out of bounds in: %s", buffer);
|
|
exit(1);
|
|
}
|
|
if(!isdigit(*line)) {
|
|
line++;
|
|
continue;
|
|
}
|
|
|
|
int num = (int) strtol(line, &line, 10);
|
|
card.givenNumbers[card.countGivenNumbers++] = num;
|
|
}
|
|
|
|
clist_add(list, card);
|
|
}
|
|
|
|
free(buffer);
|
|
return list;
|
|
}
|