198 lines
3.8 KiB
C
198 lines
3.8 KiB
C
#include <ctype.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "../libs/buffered_reader.h"
|
|
#include "../libs/data_structures.h"
|
|
|
|
#define MAX_RED 12
|
|
#define MAX_GREEN 13
|
|
#define MAX_BLUE 14
|
|
|
|
int decodea(char *str);
|
|
int decodeb(char *str);
|
|
int get_color(const char *str);
|
|
bool validate_round(char *str, int dice[]);
|
|
// SEPARATORS
|
|
const char *GAME_SEP = ":";
|
|
const char *COLOR_SEP = ",";
|
|
const char *ROUND_SEP = ";";
|
|
// COLOR
|
|
const char *RED = "red";
|
|
const char *GREEN = "green";
|
|
const char *BLUE = "blue";
|
|
|
|
list *stack;
|
|
|
|
enum Color { Red = 0, Green = 1, Blue = 2 };
|
|
|
|
int main(int argc, char *argv[]) {
|
|
if (argc < 3) {
|
|
printf("usage: day2 INPUT_FILE a|b\n");
|
|
exit(1);
|
|
}
|
|
|
|
char part = *argv[2];
|
|
|
|
filelines *lines = flines(argv[1]);
|
|
|
|
if (lines == NULL) {
|
|
printf("Failed to read file");
|
|
exit(1);
|
|
}
|
|
|
|
// init stack
|
|
initList(&stack);
|
|
|
|
int sum = 0;
|
|
for (int i = 0; i < lines->size; i++) {
|
|
int d = 0;
|
|
//based on cli input change function
|
|
switch (part) {
|
|
case 'a':
|
|
d = decodea(get(lines, i));
|
|
break;
|
|
case 'b':
|
|
d = decodeb(get(lines, i));
|
|
break;
|
|
}
|
|
|
|
/*
|
|
if (d == 0) {
|
|
printf("^^^^ Game %d ^^^^^\n", i + 1);
|
|
} else {
|
|
printf("---- Game %d -----\n", i + 1);
|
|
}
|
|
*/
|
|
|
|
sum += d;
|
|
}
|
|
printf("Sum: %d\n", sum);
|
|
}
|
|
|
|
int decodea(char *str) {
|
|
// find semicolon
|
|
int game_split = strcspn(str, GAME_SEP);
|
|
char *game_str = str + game_split + 1;
|
|
if (!*game_str || str == game_str) {
|
|
printf("Could not find game separator.\n");
|
|
exit(1);
|
|
}
|
|
|
|
// parse colors
|
|
char *token;
|
|
token = strtok(game_str, ";");
|
|
|
|
filelines *rounds;
|
|
initFileLines(&rounds);
|
|
|
|
// Get rounds
|
|
while (token) {
|
|
insert(rounds, token);
|
|
token = strtok(NULL, ";");
|
|
}
|
|
|
|
// validate rounds
|
|
for (int i = 0; i < rounds->size; i++) {
|
|
int dice[] = {0, 0, 0};
|
|
if (!validate_round(get(rounds, i), dice)) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
freeLines(rounds);
|
|
clears(stack);
|
|
int space_index = strcspn(str, " ");
|
|
for (int i = space_index + 1; i < game_split; i++) {
|
|
pushs(stack, *(str + i));
|
|
}
|
|
|
|
return atoi(contents(stack));
|
|
}
|
|
|
|
int decodeb(char *str) {
|
|
// find semicolon
|
|
int game_split = strcspn(str, GAME_SEP);
|
|
char *game_str = str + game_split + 1;
|
|
if (!*game_str || str == game_str) {
|
|
printf("Could not find game separator.\n");
|
|
exit(1);
|
|
}
|
|
|
|
// parse colors
|
|
char *token;
|
|
token = strtok(game_str, ";");
|
|
|
|
filelines *rounds;
|
|
initFileLines(&rounds);
|
|
|
|
// Get rounds
|
|
while (token) {
|
|
insert(rounds, token);
|
|
token = strtok(NULL, ";");
|
|
}
|
|
|
|
int min[] = {0,0,0};
|
|
// validate rounds
|
|
for (int i = 0; i < rounds->size; i++) {
|
|
int dice[] = {0, 0, 0};
|
|
validate_round(get(rounds, i), dice);
|
|
min[Red] = dice[Red] >= min[Red] ? dice[Red] : min[Red];
|
|
min[Green] = dice[Green] >= min[Green] ? dice[Green] : min[Green];
|
|
min[Blue] = dice[Blue] >= min[Blue] ? dice[Blue] : min[Blue];
|
|
}
|
|
|
|
return min[Red] * min[Green] * min[Blue];
|
|
}
|
|
|
|
int get_color(const char *str) {
|
|
if (strstr(str, RED)) {
|
|
return Red;
|
|
}
|
|
if (strstr(str, GREEN)) {
|
|
return Green;
|
|
}
|
|
if (strstr(str, BLUE)) {
|
|
return Blue;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
bool validate_round(char *str, int dice[]) {
|
|
list *color_list;
|
|
initList(&color_list);
|
|
|
|
char *token;
|
|
token = strtok(str, ",");
|
|
|
|
while (token) {
|
|
// trim leading whitespace
|
|
while (isspace(*token))
|
|
token++;
|
|
|
|
// printf("%s,", token);
|
|
// actually do the stuff
|
|
clears(color_list);
|
|
char *c = token;
|
|
while (c) {
|
|
if (isspace(*c)) {
|
|
break;
|
|
}
|
|
pushs(color_list, *c);
|
|
c++;
|
|
}
|
|
enum Color color = get_color(token);
|
|
dice[color] += atoi(contents(color_list));
|
|
|
|
token = strtok(NULL, ",");
|
|
}
|
|
// printf("\n");
|
|
|
|
freelist(color_list);
|
|
|
|
return dice[Red] <= MAX_RED && dice[Green] <= MAX_GREEN &&
|
|
dice[Blue] <= MAX_BLUE;
|
|
}
|