diff options
Diffstat (limited to '02.c')
-rw-r--r-- | 02.c | 165 |
1 files changed, 165 insertions, 0 deletions
@@ -0,0 +1,165 @@ +#include "input.h" + +#include <stddef.h> +#include <stdio.h> +#include <err.h> + +#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; +} |