Advertisement
Guest User

Advent Of Code - Day 21

a guest
Dec 21st, 2021
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.22 KB | None | 0 0
  1. from __future__ import annotations
  2. from collections import Counter
  3. from typing import Tuple
  4.  
  5. _rolls = []
  6. for i in range(1, 4):
  7.     for j in range(1, 4):
  8.         for k in range(1, 4):
  9.             _rolls.append(i + j + k)
  10. POTENTIAL_ROLLS = Counter(_rolls)
  11.  
  12. @dataclass
  13. class Universe:
  14.     positions: Tuple[int, int]
  15.     scores: Tuple[int, int]
  16.     count: int
  17.    
  18.     @classmethod
  19.     def create(cls, start_position_1: int, start_position_2: int) -> Universe:
  20.         return Universe((start_position_1 - 1, start_position_2 - 1), (0, 0), 1)
  21.    
  22.     def __hash__(self):
  23.         return hash(self.__repr__())
  24.    
  25.     @property
  26.     def key(self):
  27.         return f"Universe[{self.positions}, {self.scores}]"
  28.    
  29.     @property
  30.     def is_finised(self):
  31.         return self.scores[0] >= 21 or self.scores[1] >= 21
  32.    
  33.     @property
  34.     def winner(self):
  35.         if not self.is_finised:
  36.             raise Exception("Game is not finished")
  37.         return 1 if self.scores[0] >= 21 else 2
  38.    
  39.     def add(self, other: Universe):
  40.         if not self.key == other.key:
  41.             raise Exception("These are not the same Universes")
  42.         self.count += other.count
  43.    
  44.     def roll(self, player: int):
  45.         new_universes = {}
  46.         for roll, count in POTENTIAL_ROLLS.items():
  47.             if player == 1:
  48.                 new_position = (self.positions[0] + roll) % 10
  49.                 new_score = self.scores[0] + (new_position + 1)
  50.                 universe = Universe(
  51.                     (new_position, self.positions[1]),
  52.                     (new_score, self.scores[1]),
  53.                     self.count * count
  54.                 )
  55.             elif player == 2:
  56.                 new_position = (self.positions[1] + roll) % 10
  57.                 new_score = self.scores[1] + (new_position + 1)
  58.                 universe = Universe(
  59.                     (self.positions[0], new_position),
  60.                     (self.scores[0], new_score),
  61.                     self.count * count
  62.                 )
  63.             else:
  64.                 raise Exception("Bruh! This is a 2 player game yo!")
  65.                
  66.             if universe.key not in new_universes:
  67.                 new_universes[universe.key] = universe
  68.             else:
  69.                 new_universes[universe.key].add(universe)
  70.        
  71.         return list(new_universes.values())
  72.  
  73. current_universes = [Universe.create(10, 1)]
  74. finished_games = {}
  75.  
  76. player_turn = 1
  77. while current_universes:
  78.     new_universes = {}
  79.     for current in current_universes:
  80.         for new in current.roll(player_turn):
  81.            
  82.             if new.is_finised:
  83.                 if new.key not in finished_games:
  84.                     finished_games[new.key] = new
  85.                 else:
  86.                     finished_games[new.key].add(new)
  87.             else:
  88.                 if new.key not in new_universes:
  89.                     new_universes[new.key] = new
  90.                 else:
  91.                     new_universes[new.key].add(new)
  92.                
  93.                
  94.     current_universes = list(new_universes.values())
  95.     player_turn = 2 if player_turn == 1 else 1
  96.    
  97. wins = {1: 0, 2: 0}
  98. for universe in finished_games.values():
  99.     wins[universe.winner] += universe.count
  100. wins
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement