Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdbool.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- int part1(int start_p1, int start_p2) {
- // player positions
- int p1 = start_p1;
- int p2 = start_p2;
- // player scores
- int p1_score = 0;
- int p2_score = 0;
- // die stuff
- int die = 0;
- int roll_count = 0;
- // turn switch
- bool p1_goes = true;
- while (p1_score < 1000 && p2_score < 1000) {
- // Roll the die 3 times
- int total_roll = (++die % 100) + (++die % 100) + (++die % 100);
- total_roll %= 10;
- roll_count += 3;
- // move the correct player
- if (p1_goes) {
- p1 += total_roll;
- if (p1 > 10) p1 -= 10;
- p1_score += p1;
- p1_goes = false;
- } else {
- p2 += total_roll;
- if (p2 > 10) p2 -= 10;
- p2_score += p2;
- p1_goes = true;
- }
- }
- // printf("p1 score: %d, p2 score: %d, roll count: %d\n", p1_score, p2_score, roll_count);
- if (p1_score >= 1000) {
- return p2_score * roll_count;
- } else {
- return p1_score * roll_count;
- }
- }
- // roll combos are:
- // 1-1-1, 1-1-2, 1-1-3, 1-2-1, 1-2-2, 1-2-3, 1-3-1, 1-3-2, 1-3-3,
- // 2-1-1, 2-1-2, 2-1-3, 2-2-1, 2-2-2, 2-2-3, 2-3-1, 2-3-2, 2-3-3,
- // 3-1-1, 3-1-2, 3-1-3, 3-2-1, 3-2-2, 3-2-3, 3-3-1, 3-3-2, 3-3-3
- int rolls[27] = {
- 3, 4, 5, 4, 5, 6, 5, 6, 7, // 1x3, 2x4, 3x5, 2x6, 1x7
- 4, 5, 6, 5, 6, 7, 6, 7, 8, // 1x4, 2x5, 3x6, 2x7, 1x8
- 5, 6, 7, 6, 7, 8, 7, 8, 9 // 1x5, 2x6, 3x7, 2x8, 1x9
- };
- // TODO: uses this to collapse keep_moving to use 7 iterations, rather than 27.
- // 1x3, 3x4, 6x5, 7x6, 6x7, 3x8, 1x9
- unsigned long long invocations = 0;
- unsigned long long overflows = 0;
- void keep_moving(bool p1_moves, unsigned long long* p1_wins, unsigned long long*
- p2_wins, int p1, int p2, int p1_score, int p2_score, int depth) {
- assert(p1_score < 21);
- assert(1 <= p1 && p1 <= 10);
- assert(p2_score < 21);
- assert(1 <= p2 && p2 <= 10);
- ++invocations;
- printf("Depth: %d ", depth);
- for (int i = 0; i < 27; ++i) {
- if (p1_moves) {
- p1 += rolls[i];
- while (p1 > 10) {
- p1 -= 10;
- }
- p1_score += p1;
- // printf("moving p1 by %d (roll %d) to position %d with score %d\n", rolls[i], i, p1, p1_score);
- if (p1_score >= 21) {
- ++(*p1_wins);
- } else {
- p1_moves = false;
- keep_moving(p1_moves, p1_wins, p2_wins, p1, p2, p1_score, p2_score,
- (depth+1));
- }
- } else {
- p2 += rolls[i];
- while (p2 > 10) {
- p2 -= 10;
- }
- p2_score += p2;
- if (p2_score >= 21) {
- ++(*p2_wins);
- } else {
- p1_moves = true;
- keep_moving(p1_moves, p1_wins, p2_wins, p1, p2, p1_score, p2_score,
- (depth+1));
- }
- }
- }
- }
- unsigned long long part2(int start_p1, int start_p2) {
- unsigned long long p1_wins = 0;
- unsigned long long p2_wins = 0;
- int p1 = start_p1;
- int p2 = start_p2;
- int p1_score = 0;
- int p2_score = 0;
- bool p1_moves = true;
- keep_moving(p1_moves, &p1_wins, &p2_wins, p1, p2, p1_score, p2_score, 0);
- printf("Player 1 wins %llu times.\nPlayer 2 wins %llu times\n", p1_wins, p2_wins);
- return p1_wins > p2_wins ? p1_wins : p2_wins;
- }
- int main() {
- int p1, p2;
- int ret = scanf("Player 1 starting position: %d ", &p1);
- if (ret < 1) {
- fprintf(stderr, "player 1's input not found");
- }
- ret = scanf("Player 2 starting position: %d ", &p2);
- if (ret < 1) {
- fprintf(stderr, "player 2's input not found");
- }
- printf("P1: %d, p2: %d\n", p1, p2);
- printf("%d\n", part1(p1, p2));
- printf("%llu\n", part2(p1, p2));
- printf("Invocations: %llu\n", invocations);
- }
Advertisement
Add Comment
Please, Sign In to add comment