Advertisement
Guest User

Untitled

a guest
Dec 20th, 2021
293
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.33 KB | None | 0 0
  1. import numpy as np
  2. from collections import defaultdict
  3.  
  4. def part_2():
  5.  
  6.   #no, I don't know why I made this a numpy array
  7.   roll_counts = np.zeros([10])
  8.   #count how many different ways there are to roll each possible value
  9.   for x in range(1,4):
  10.     for y in range(1,4):
  11.       for z in range(1,4):
  12.         roll_counts[x+y+z] += 1
  13.  
  14.  
  15.   #same as part_1
  16.   x = 1
  17.   y = 10
  18.  
  19.   #so the basic idea is that there's a relatively small number of states the game
  20.   #can be in, and we just need to count how many universes are in each possible state
  21.   #then, when we go to take a turn, we can update them in batches
  22.  
  23.   #the dict will map a state tuple (x,y,x_score,y_score) to a count, where the
  24.   #count says how many parallel universes (thx pannen) end up in that state
  25.   #x y x_score y_score
  26.   states = {(x,y,0,0): 1}
  27.   x_turn = True #whose turn it is
  28.  
  29.   #how many times each player has won
  30.   x_wins = 0
  31.   y_wins = 0
  32.   while len(states)>0:
  33.    
  34.     new_states = defaultdict(int)
  35.     for s in states.keys(): #loop over the current valid states
  36.       for roll in range(3,10): #loop over all possible rolls
  37.         if x_turn: #check whose turn it is
  38.           new_x = (s[0] + roll - 1)%10 + 1 #move the piece
  39.           new_score = s[2] + new_x #updat the score
  40.           if new_score >= 21:
  41.             #if we won, the number of universes that reach this conclusion is
  42.             #the number of ways we could have ended up in the state times the number
  43.             #of ways we could have made the current roll
  44.             x_wins += states[s]*roll_counts[roll]
  45.           else:
  46.             #otherwise, we didn't win, and we just update the count for the new state
  47.             new_states[(new_x,s[1],new_score,s[3])]+=states[s]*roll_counts[roll]
  48.        
  49.         #same plan for y
  50.         else:
  51.           new_y = (s[1] + roll - 1)%10 + 1
  52.           new_score = s[3] + new_y
  53.           if new_score >= 21:
  54.             y_wins += states[s]*roll_counts[roll]
  55.           else:
  56.             new_states[(s[0],new_y,s[2],new_score)]+=states[s]*roll_counts[roll]
  57.     x_turn = not x_turn
  58.     states = new_states
  59.  
  60.   print(max(x_wins,y_wins))
  61.  
  62.  
  63.  
  64. def part_1():
  65.  
  66.   #this is extremely boring and straight-forward, we just do the thing the
  67.   #problem says to do until someone wins.
  68.  
  69.   global roll_counter
  70.   #x and y will track the two players' positions
  71.   x = 1
  72.   y = 10
  73.  
  74.   #and scores
  75.   x_score = 0
  76.   y_score = 0
  77.   while x_score<1000 and y_score<1000:
  78.     x_move = roll() + roll() + roll()
  79.     x += x_move
  80.     x = (x-1)%10 + 1 #what sort of stupid game is 1-indexed?
  81.     x_score += x
  82.  
  83.     #if x wins, y doesn't get a turn
  84.     if x_score >= 1000:
  85.       break
  86.  
  87.     y_move = roll() + roll() + roll()
  88.     y += y_move
  89.     y = (y-1)%10 + 1
  90.     y_score += y
  91.  
  92.   #if x wins, we need to print y's score, otherwise x's score
  93.   if x_score >= 1000:
  94.     print(roll_counter*y_score)
  95.   else:
  96.     print(roll_counter*x_score)
  97.  
  98. #did you know that if you try to make a variable and function with the same name,
  99. #things might go poorly?
  100. rollz = 1 #track the next number to be rolled
  101. roll_counter = 0 #track how many times we've rolled
  102. def roll():
  103.   #global variables are gross, but fast to write!
  104.   global rollz
  105.   global roll_counter
  106.   roll_counter+=1
  107.   result = rollz
  108.   rollz+=1
  109.   if rollz == 101:
  110.     rollz = 1
  111.   return result
  112.  
  113. part_1()
  114. part_2()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement