#include "input.h" #include #include #include #define INPUT "input/02.txt" #define EXPECTED1 13221L #define EXPECTED2 13131L enum draw { rock = 1, paper = 2, scissors = 3, }; struct round_p1 { enum draw opponent; enum draw me; }; int compute_round_score_p1(struct round_p1* round) { int score = (int) round->me; enum draw opponent = round->opponent; enum draw me = round->me; if((opponent == rock && me == paper) || (opponent == paper && me == scissors) || (opponent == scissors && me == rock)) score += 6; // win else if(opponent == me) score += 3; // draw // loss is 0 return score; } void parse_round_p1(struct round_p1* round, char* round_str) { switch(round_str[0]) { case 'A': round->opponent = rock; break; case 'B': round->opponent = paper; break; case 'C': round->opponent = scissors; break; default: err(2, "unknown opponent choice %c", round_str[0]); } switch(round_str[2]) { case 'X': round->me = rock; break; case 'Y': round->me = paper; break; case 'Z': round->me = scissors; break; default: err(2, "unknown me choice %c", round_str[2]); } } void part1(struct input_str* input) { // compute max calories long score = 0; struct round_p1 r; for(size_t i = 0; i < input->line_count; i++) { parse_round_p1(&r, input->lines[i]); int round_score = compute_round_score_p1(&r); score += round_score; } CHECK(score, EXPECTED1) } enum round_result { loss = 0, draw = 3, win = 6, }; struct round_p2 { enum draw opponent; enum round_result result; }; int compute_round_score_p2(struct round_p2* round) { enum draw opponent = round->opponent; enum round_result result = round->result; enum draw me; switch(result) { case loss: if(opponent == rock) me = scissors; else me = (enum draw) ((int) opponent - 1); break; case draw: me = opponent; break; case win: if(opponent == scissors) me = rock; else me = (enum draw) ((int) opponent + 1); break; } return (int) me + (int) result; } void parse_round_p2(struct round_p2* round, char* round_str) { switch(round_str[0]) { case 'A': round->opponent = rock; break; case 'B': round->opponent = paper; break; case 'C': round->opponent = scissors; break; default: err(2, "unknown opponent choice %c", round_str[0]); } switch(round_str[2]) { case 'X': round->result = loss; break; case 'Y': round->result = draw; break; case 'Z': round->result = win; break; default: err(2, "unknown expected result %c", round_str[2]); } } void part2(struct input_str* input) { // compute max calories long score = 0; struct round_p2 r; for(size_t i = 0; i < input->line_count; i++) { parse_round_p2(&r, input->lines[i]); int round_score = compute_round_score_p2(&r); score += round_score; } CHECK(score, EXPECTED2) } int main() { // read input struct input_str input; input_str_read(&input, INPUT); // do stuff part1(&input); part2(&input); // cleanup & exit input_str_free(&input); return 0; }