mirror of
https://codeberg.org/andyscott/advent-of-code.git
synced 2024-12-22 17:43:10 -05:00
118 lines
2.6 KiB
C
118 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;
|
||
|
}
|