-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathp084.py
82 lines (65 loc) · 2.13 KB
/
p084.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#
# Solution to Project Euler problem 84
import random
# This is a statistical sampling approximation algorithm that simply simulates the game for a fixed number of dice rolls.
# An exact algorithm would involve calculating the eigenvector of the largest eigenvalue of the transition matrix (which is practical),
# but averaging over all possible permutations of both the Chance and Community Chest decks (which is computationally infeasible).
def compute():
TRIALS = 10**7
visitcounts = [0] * 40
chance = CardDeck(16)
communitychest = CardDeck(16)
consecutivedoubles = 0
location = 0
for i in range(TRIALS):
# Roll tetrahedral dice
die0 = random.randint(1, 4)
die1 = random.randint(1, 4)
consecutivedoubles = (consecutivedoubles + 1) if (die0 == die1) else 0
if consecutivedoubles < 3:
location = (location + die0 + die1) % 40
else:
location = 30
consecutivedoubles = 0
# Process actions for some locations
if location in (7, 22, 36): # Chance
card = chance.next_card()
if card == 0: location = 0
elif card == 1: location = 10
elif card == 2: location = 11
elif card == 3: location = 24
elif card == 4: location = 39
elif card == 5: location = 5
elif card in (6, 7): # Next railway
location = (location + 5) // 10 % 4 * 10 + 5
elif card == 8: # Next utility
location = 28 if (12 < location < 28) else 12
elif card == 9:
location -= 3
else:
pass
elif location == 30: # Go to jail
location = 10
else:
pass
if location in (2, 17, 33): # Community chest
card = communitychest.next_card()
if card == 0: location = 0
elif card == 1: location = 10
visitcounts[location] += 1
temp = sorted(enumerate(visitcounts), key=(lambda ic: -ic[1]))
ans = "".join("{:02d}".format(i) for (i, c) in temp[ : 3])
return str(ans)
class CardDeck(object):
def __init__(self, size):
self.cards = list(range(size))
self.index = size
def next_card(self):
if self.index == len(self.cards):
random.shuffle(self.cards)
self.index = 0
result = self.cards[self.index]
self.index += 1
return result
if __name__ == "__main__":
print(compute())