advent-of-code/2022/2.c

117 lines
2.6 KiB
C

#include <stdio.h>
#include <string.h>
struct RPS_Game {
// Part 1 Rock / Part 2 Lose
const int X;
// Part 1 Paper / Part 2 Draw
const int Y;
// Part 1 Scissors / Part 2 Win
const int Z;
// Outcomes
const int draw;
const int win;
};
// Part 1 - Calculate score
void process_round(struct RPS_Game *game, int *score, const char opponent_move,
const char my_move) {
switch (my_move) {
case 'X': // Rock
*score += game->X;
if (opponent_move == 'A') {
*score += game->draw;
} else if (opponent_move == 'C') {
*score += game->win;
}
break;
case 'Y': // Paper
*score += game->Y;
if (opponent_move == 'A') {
*score += game->win;
} else if (opponent_move == 'B') {
*score += game->draw;
}
break;
case 'Z': // Scissors
*score += game->Z;
if (opponent_move == 'B') {
*score += game->win;
} else if (opponent_move == 'C') {
*score += game->draw;
}
break;
}
}
// Part 2 - Find move given a desired result, then calculate score
void find_move(struct RPS_Game *game, int *score, const char opponent_move,
const char result) {
char my_move = '\0';
switch (result) {
case 'X': // need to lose
if (opponent_move == 'A') {
my_move = 'Z';
} else if (opponent_move == 'B') {
my_move = 'X';
} else if (opponent_move == 'C') {
my_move = 'Y';
}
break;
case 'Y': // need a draw
if (opponent_move == 'A') {
my_move = 'X';
} else if (opponent_move == 'B') {
my_move = 'Y';
} else if (opponent_move == 'C') {
my_move = 'Z';
}
break;
case 'Z': // need to win
if (opponent_move == 'A') {
my_move = 'Y';
} else if (opponent_move == 'B') {
my_move = 'Z';
} else if (opponent_move == 'C') {
my_move = 'X';
}
break;
}
process_round(game, score, opponent_move, my_move);
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "USAGE: %s input_file\n", argv[0]);
return 1;
}
FILE *file = fopen(argv[1], "r");
if (!file) {
fprintf(stderr, "Error opening file %s\n", argv[1]);
return 1;
}
int part1_score = 0;
int part2_score = 0;
char round[5] = {0};
struct RPS_Game game = {.X = 1, .Y = 2, .Z = 3, .draw = 3, .win = 6};
while (fgets(round, sizeof round / sizeof *round, file) != NULL) {
if (strlen(round) == 1) {
break;
}
process_round(&game, &part1_score, round[0], round[2]);
find_move(&game, &part2_score, round[0], round[2]);
}
fclose(file);
printf("My part 1 score: %d\n", part1_score);
printf("My part 2 score: %d\n", part2_score);
return 0;
}