Douma37

aoc2021/day21

Dec 30th, 2021
1,350
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.61 KB | None | 0 0
  1. #include <stdbool.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <assert.h>
  6.  
  7. int part1(int start_p1, int start_p2) {
  8.   // player positions
  9.   int p1 = start_p1;
  10.   int p2 = start_p2;
  11.   // player scores
  12.   int p1_score = 0;
  13.   int p2_score = 0;
  14.   // die stuff
  15.   int die = 0;
  16.   int roll_count = 0;
  17.   // turn switch
  18.   bool p1_goes = true;
  19.   while (p1_score < 1000 && p2_score < 1000) {
  20.     // Roll the die 3 times
  21.     int total_roll = (++die % 100) + (++die % 100) + (++die % 100);
  22.     total_roll %= 10;
  23.     roll_count += 3;
  24.     // move the correct player
  25.     if (p1_goes) {
  26.       p1 += total_roll;
  27.       if (p1 > 10) p1 -= 10;
  28.       p1_score += p1;
  29.       p1_goes = false;
  30.     } else {
  31.       p2 += total_roll;
  32.       if (p2 > 10) p2 -= 10;
  33.       p2_score += p2;
  34.       p1_goes = true;
  35.     }
  36.   }
  37.   // printf("p1 score: %d, p2 score: %d, roll count: %d\n", p1_score, p2_score, roll_count);
  38.   if (p1_score >= 1000) {
  39.     return p2_score * roll_count;
  40.   } else {
  41.     return p1_score * roll_count;
  42.   }
  43. }
  44.  
  45. // roll combos are:
  46. // 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,
  47. // 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,
  48. // 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
  49. int rolls[27] = {
  50.   3, 4, 5, 4, 5, 6, 5, 6, 7, // 1x3, 2x4, 3x5, 2x6, 1x7
  51.   4, 5, 6, 5, 6, 7, 6, 7, 8, //      1x4, 2x5, 3x6, 2x7, 1x8
  52.   5, 6, 7, 6, 7, 8, 7, 8, 9  //           1x5, 2x6, 3x7, 2x8, 1x9
  53. };
  54. // TODO: uses this to collapse keep_moving to use 7 iterations, rather than 27.
  55. // 1x3, 3x4, 6x5, 7x6, 6x7, 3x8, 1x9
  56.  
  57. unsigned long long invocations = 0;
  58. unsigned long long overflows = 0;
  59.  
  60. void keep_moving(bool p1_moves, unsigned long long* p1_wins, unsigned long long*
  61.   p2_wins, int p1, int p2, int p1_score, int p2_score, int depth) {
  62.   assert(p1_score < 21);
  63.   assert(1 <= p1 && p1 <= 10);
  64.   assert(p2_score < 21);
  65.   assert(1 <= p2 && p2 <= 10);
  66.   ++invocations;
  67.   printf("Depth: %d ", depth);
  68.  
  69.   for (int i = 0; i < 27; ++i) {
  70.     if (p1_moves) {
  71.       p1 += rolls[i];
  72.       while (p1 > 10) {
  73.         p1 -= 10;
  74.       }
  75.       p1_score += p1;
  76.       // printf("moving p1 by %d (roll %d) to position %d with score %d\n", rolls[i], i, p1, p1_score);
  77.       if (p1_score >= 21) {
  78.         ++(*p1_wins);
  79.       } else {
  80.         p1_moves = false;
  81.         keep_moving(p1_moves, p1_wins, p2_wins, p1, p2, p1_score, p2_score,
  82.         (depth+1));
  83.       }
  84.     } else {
  85.       p2 += rolls[i];
  86.       while (p2 > 10) {
  87.         p2 -= 10;
  88.       }
  89.       p2_score += p2;
  90.       if (p2_score >= 21) {
  91.         ++(*p2_wins);
  92.       } else {
  93.         p1_moves = true;
  94.         keep_moving(p1_moves, p1_wins, p2_wins, p1, p2, p1_score, p2_score,
  95.         (depth+1));
  96.       }
  97.     }
  98.   }
  99. }
  100.  
  101. unsigned long long part2(int start_p1, int start_p2) {
  102.   unsigned long long p1_wins = 0;
  103.   unsigned long long p2_wins = 0;
  104.   int p1 = start_p1;
  105.   int p2 = start_p2;
  106.   int p1_score = 0;
  107.   int p2_score = 0;
  108.   bool p1_moves = true;
  109.   keep_moving(p1_moves, &p1_wins, &p2_wins, p1, p2, p1_score, p2_score, 0);
  110.   printf("Player 1 wins %llu times.\nPlayer 2 wins %llu times\n", p1_wins, p2_wins);
  111.   return p1_wins > p2_wins ? p1_wins : p2_wins;
  112. }
  113.  
  114. int main() {
  115.   int p1, p2;
  116.   int ret = scanf("Player 1 starting position: %d ", &p1);
  117.   if (ret < 1) {
  118.     fprintf(stderr, "player 1's input not found");
  119.   }
  120.   ret = scanf("Player 2 starting position: %d ", &p2);
  121.   if (ret < 1) {
  122.     fprintf(stderr, "player 2's input not found");
  123.   }
  124.   printf("P1: %d, p2: %d\n", p1, p2);
  125.   printf("%d\n", part1(p1, p2));
  126.   printf("%llu\n", part2(p1, p2));
  127.   printf("Invocations: %llu\n", invocations);
  128. }
Advertisement
Add Comment
Please, Sign In to add comment