2
1
Fork 0

Day 21: Add C solution

This commit is contained in:
Mia Herkt 2021-12-21 21:58:17 +01:00
parent 6b8b9ea6ed
commit 27c8920b2a
Signed by: mia
GPG key ID: 72E154B8622EC191
3 changed files with 85 additions and 0 deletions

2
21/input.txt Normal file
View file

@ -0,0 +1,2 @@
Player 1 starting position: 7
Player 2 starting position: 8

54
21/problem.html Normal file
View file

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, text/html, charset=UTF-8" http-equiv="Content-Type">
</meta>
<title>Day 21 - Advent of Code 2021</title>
<style type="text/css">
body {
margin: 30px auto;
max-width: 650px;
line-height: 1.4;
padding: 0 10px;
}
h1, h2, h3 {
line-height: 1.2;
}
</style>
</head><div id="readability-page-1" class="page"><article><h2>--- Day 21: Dirac Dice ---</h2><p>There's not much to do as you slowly descend to the bottom of the ocean. The submarine computer <span title="A STRANGE GAME.">challenges you to a nice game</span> of <em>Dirac Dice</em>.</p>
<p>This game consists of a single <a href="https://en.wikipedia.org/wiki/Dice" target="_blank">die</a>, two <a href="https://en.wikipedia.org/wiki/Glossary_of_board_games#piece" target="_blank">pawns</a>, and a game board with a circular track containing ten spaces marked <code>1</code> through <code>10</code> clockwise. Each player's <em>starting space</em> is chosen randomly (your puzzle input). Player 1 goes first.</p>
<p>Players take turns moving. On each player's turn, the player rolls the die <em>three times</em> and adds up the results. Then, the player moves their pawn that many times <em>forward</em> around the track (that is, moving clockwise on spaces in order of increasing value, wrapping back around to <code>1</code> after <code>10</code>). So, if a player is on space <code>7</code> and they roll <code>2</code>, <code>2</code>, and <code>1</code>, they would move forward 5 times, to spaces <code>8</code>, <code>9</code>, <code>10</code>, <code>1</code>, and finally stopping on <code>2</code>.</p>
<p>After each player moves, they increase their <em>score</em> by the value of the space their pawn stopped on. Players' scores start at <code>0</code>. So, if the first player starts on space <code>7</code> and rolls a total of <code>5</code>, they would stop on space <code>2</code> and add <code>2</code> to their score (for a total score of <code>2</code>). The game immediately ends as a win for any player whose score reaches <em>at least <code>1000</code></em>.</p>
<p>Since the first game is a practice game, the submarine opens a compartment labeled <em>deterministic dice</em> and a 100-sided die falls out. This die always rolls <code>1</code> first, then <code>2</code>, then <code>3</code>, and so on up to <code>100</code>, after which it starts over at <code>1</code> again. Play using this die.</p>
<p>For example, given these starting positions:</p>
<pre><code>Player 1 starting position: 4
Player 2 starting position: 8
</code></pre>
<p>This is how the game would go:</p>
<ul>
<li>Player 1 rolls <code>1</code>+<code>2</code>+<code>3</code> and moves to space <code>10</code> for a total score of <code>10</code>.</li>
<li>Player 2 rolls <code>4</code>+<code>5</code>+<code>6</code> and moves to space <code>3</code> for a total score of <code>3</code>.</li>
<li>Player 1 rolls <code>7</code>+<code>8</code>+<code>9</code> and moves to space <code>4</code> for a total score of <code>14</code>.</li>
<li>Player 2 rolls <code>10</code>+<code>11</code>+<code>12</code> and moves to space <code>6</code> for a total score of <code>9</code>.</li>
<li>Player 1 rolls <code>13</code>+<code>14</code>+<code>15</code> and moves to space <code>6</code> for a total score of <code>20</code>.</li>
<li>Player 2 rolls <code>16</code>+<code>17</code>+<code>18</code> and moves to space <code>7</code> for a total score of <code>16</code>.</li>
<li>Player 1 rolls <code>19</code>+<code>20</code>+<code>21</code> and moves to space <code>6</code> for a total score of <code>26</code>.</li>
<li>Player 2 rolls <code>22</code>+<code>23</code>+<code>24</code> and moves to space <code>6</code> for a total score of <code>22</code>.</li>
</ul>
<p>...after many turns...</p>
<ul>
<li>Player 2 rolls <code>82</code>+<code>83</code>+<code>84</code> and moves to space <code>6</code> for a total score of <code>742</code>.</li>
<li>Player 1 rolls <code>85</code>+<code>86</code>+<code>87</code> and moves to space <code>4</code> for a total score of <code>990</code>.</li>
<li>Player 2 rolls <code>88</code>+<code>89</code>+<code>90</code> and moves to space <code>3</code> for a total score of <code>745</code>.</li>
<li>Player 1 rolls <code>91</code>+<code>92</code>+<code>93</code> and moves to space <code>10</code> for a final score, <code>1000</code>.</li>
</ul>
<p>Since player 1 has at least <code>1000</code> points, player 1 wins and the game ends. At this point, the losing player had <code>745</code> points and the die had been rolled a total of <code>993</code> times; <code>745 * 993 = <em>739785</em></code>.</p>
<p>Play a practice game using the deterministic 100-sided die. The moment either player wins, <em>what do you get if you multiply the score of the losing player by the number of times the die was rolled during the game?</em></p>
</article><p>Your puzzle answer was <code>556206</code>.</p><article><h2 id="part2">--- Part Two ---</h2><p>Now that you're warmed up, it's time to play the real game.</p>
<p>A second compartment opens, this time labeled <em>Dirac dice</em>. Out of it falls a single three-sided die.</p>
<p>As you experiment with the die, you feel a little strange. An informational brochure in the compartment explains that this is a <em>quantum die</em>: when you roll it, the universe <em>splits into multiple copies</em>, one copy for each possible outcome of the die. In this case, rolling the die always splits the universe into <em>three copies</em>: one where the outcome of the roll was <code>1</code>, one where it was <code>2</code>, and one where it was <code>3</code>.</p>
<p>The game is played the same as before, although to prevent things from getting too far out of hand, the game now ends when either player's score reaches at least <code><em>21</em></code>.</p>
<p>Using the same starting positions as in the example above, player 1 wins in <code><em>444356092776315</em></code> universes, while player 2 merely wins in <code>341960390180808</code> universes.</p>
<p>Using your given starting positions, determine every possible outcome. <em>Find the player that wins in more universes; in how many universes does that player win?</em></p>
</article><p>Your puzzle answer was <code>630797200227453</code>.</p></div>

29
21/solution.c Normal file
View file

@ -0,0 +1,29 @@
#include <stdio.h>
M( p,s){ return(p
+s-1)% 10+1;}S( int*p,int*d,
int* D){for(int s= 0;s<3;s++,(
*D) ++)(*p)=M(* p,* d=*d%100+1
);return*p;}x(l,r ){int L=0,R=0
,d=0,D=0;for(;; ){L+=S(
&l,&d,&D); if(L>=
1000) break;R
+=S(&r, &d,&D);
if( R >= 1000)break
;}return D* (L>R?R:L);}
size_t X(t, l,r,L,R){if(L >=21
||R >= 21 ) return t;static F[ ]={1,3,6
,7 , 6,3,1}; size_t s=0;for( int m=0;m<7;
m++ ){int o=l, O= L,g=r,G=R
;if (t)G+=g=M(r ,m +3);else
O+=o=M(l,m+3);s+=F[ m] *X(! t,o,g,O
,G);}return s;}main ( int p, char* * P)
{ int l =4,r=8 ;if( p ==3
){ l= atoi(P[ 1 ]);
r=atoi (P[2 ] );
}printf("" "" "Si"
"lver: %" "" "d"
"\nGold: " "" "%lu\n"
,x(l,r),X ( 0,l,r,
0,0));}