21_dice.py 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. #!/usr/bin/env python3
  2. import sys
  3. from itertools import cycle, product
  4. from functools import lru_cache
  5. def move(pos, score, amount):
  6. pos = (pos + amount - 1) % 10 + 1
  7. return pos, score + pos
  8. def practice(a, b):
  9. players = [(a, 0), (b, 0)]
  10. die = cycle(range(1, 101))
  11. rolls = 0
  12. while True:
  13. for player, (pos, score) in enumerate(players):
  14. roll = next(die) + next(die) + next(die)
  15. rolls += 3
  16. pos, score = players[player] = move(pos, score, roll)
  17. if score >= 1000:
  18. otherpos, otherscore = players[1 - player]
  19. return rolls * otherscore
  20. def play(a, b):
  21. @lru_cache(maxsize=None)
  22. def wins(a, b):
  23. awins = bwins = 0
  24. for rolls in product(range(1, 4), repeat=3):
  25. pos, score = roll_a = move(*a, sum(rolls))
  26. if score >= 21:
  27. awins += 1
  28. else:
  29. roll_bwins, roll_awins = wins(b, roll_a)
  30. awins += roll_awins
  31. bwins += roll_bwins
  32. return awins, bwins
  33. return max(wins((a, 0), (b, 0)))
  34. a, b = (int(line.split(': ')[-1]) for line in sys.stdin)
  35. print(practice(a, b))
  36. print(play(a, b))