mirror of
https://github.com/peter-tanner/advent-of-code-2021.git
synced 2024-11-30 11:10:20 +08:00
Day 21 solutions
This commit is contained in:
parent
de364fabff
commit
f1fedda1ac
71
21/21-1.c
Normal file
71
21/21-1.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "../check_alloc.h"
|
||||
|
||||
#define P1_START 4
|
||||
#define P2_START 8
|
||||
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int position;
|
||||
int score;
|
||||
} PLAYER;
|
||||
|
||||
PLAYER *new_player(int initial_position)
|
||||
{
|
||||
PLAYER *p_player = calloc(1, sizeof(PLAYER));
|
||||
CHECK_ALLOC(p_player);
|
||||
p_player->position = initial_position;
|
||||
return p_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 struct
|
||||
{
|
||||
int value;
|
||||
int rolls;
|
||||
} DICE;
|
||||
|
||||
#define NEW_DICE() calloc(1, sizeof(DICE))
|
||||
|
||||
int roll_dice(DICE *dice)
|
||||
{
|
||||
dice->value = dice->value % 100 + 1;
|
||||
dice->rolls++;
|
||||
return dice->value;
|
||||
}
|
||||
int roll_3(DICE *dice)
|
||||
{
|
||||
int value = roll_dice(dice);
|
||||
value += roll_dice(dice);
|
||||
value += roll_dice(dice);
|
||||
return value;
|
||||
}
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
DICE *p_dice = NEW_DICE();
|
||||
PLAYER *p_p1 = new_player(P1_START);
|
||||
PLAYER *p_p2 = new_player(P2_START);
|
||||
while (1)
|
||||
{
|
||||
int value = roll_3(p_dice);
|
||||
move_position(p_p1, value);
|
||||
if (p_p1->score >= 1000)
|
||||
break;
|
||||
value = roll_3(p_dice);
|
||||
move_position(p_p2, value);
|
||||
if (p_p2->score >= 1000)
|
||||
break;
|
||||
}
|
||||
printf("END RESULT %d\n", p_dice->rolls * MIN(p_p1->score, p_p2->score));
|
||||
return 0;
|
||||
}
|
87
21/21-2.c
Normal file
87
21/21-2.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
#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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user