mirror of
https://github.com/peter-tanner/advent-of-code-2021.git
synced 2024-11-30 19:20:19 +08:00
88 lines
2.1 KiB
C
88 lines
2.1 KiB
C
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
// I needed some help for this one. Couldn't be bothered to implement a cache etc.
|
||
|
// I calculated the DICE array, but struggled getting the total wins. Instead of
|
||
|
// multiplying as I went up, I tried to multiply when a result occurred but
|
||
|
// obviously this was the wrong way to think about it.
|
||
|
|
||
|
#define P1_START 6
|
||
|
#define P2_START 1
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
int position;
|
||
|
int score;
|
||
|
} PLAYER;
|
||
|
|
||
|
PLAYER clone_player(PLAYER player)
|
||
|
{
|
||
|
PLAYER new_player = {player.position, player.score};
|
||
|
return new_player;
|
||
|
}
|
||
|
|
||
|
void move_position(PLAYER *player, int move)
|
||
|
{
|
||
|
int next_pos = (player->position + move) % 10;
|
||
|
player->position = next_pos == 0 ? 10 : next_pos;
|
||
|
player->score += player->position;
|
||
|
}
|
||
|
|
||
|
typedef unsigned long long NUMBER;
|
||
|
|
||
|
typedef enum
|
||
|
{
|
||
|
P1,
|
||
|
P2
|
||
|
} TURN;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
NUMBER p1_wins;
|
||
|
NUMBER p2_wins;
|
||
|
} SCORE;
|
||
|
|
||
|
// PRE-CALCULATED OCCURRENCES OF TOTALS FOR ROLLING 3 DICE
|
||
|
int DICE[] = {1, 3, 6, 7, 6, 3, 1};
|
||
|
|
||
|
// repeat TRACKS THE AMOUNT OF POSSIBLE COMBINATIONS LEADING TO A WIN,
|
||
|
// THIS REDUCES THE SEARCH AREA GREATLY BY IGNORING PATHS TO THE SAME WIN.
|
||
|
void iter_rolls(PLAYER p1, PLAYER p2, TURN turn, NUMBER repeat, SCORE *score)
|
||
|
{
|
||
|
for (int i = 0; i < 7; i++)
|
||
|
{
|
||
|
int value = i + 3;
|
||
|
PLAYER tmp;
|
||
|
if (turn == P1)
|
||
|
tmp = clone_player(p1);
|
||
|
else
|
||
|
tmp = clone_player(p2);
|
||
|
move_position(&tmp, value);
|
||
|
if (tmp.score < 21)
|
||
|
{
|
||
|
if (turn == P1)
|
||
|
iter_rolls(tmp, p2, P2, repeat * DICE[i], score);
|
||
|
else
|
||
|
iter_rolls(p1, tmp, P1, repeat * DICE[i], score);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (turn == P1)
|
||
|
score->p1_wins += repeat * DICE[i];
|
||
|
else
|
||
|
score->p2_wins += repeat * DICE[i];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int main(int argc, char const *argv[])
|
||
|
{
|
||
|
PLAYER p1 = {P1_START, 0};
|
||
|
PLAYER p2 = {P2_START, 0};
|
||
|
SCORE *p_score = malloc(sizeof(SCORE));
|
||
|
iter_rolls(p1, p2, P1, 1, p_score);
|
||
|
printf("WINNER SCORE %llu\n", p_score->p1_wins > p_score->p2_wins ? p_score->p1_wins : p_score->p2_wins);
|
||
|
return 0;
|
||
|
}
|