Skip to content

Instantly share code, notes, and snippets.

@fredyr
Created February 9, 2013 17:09
Show Gist options
  • Save fredyr/4746097 to your computer and use it in GitHub Desktop.
Save fredyr/4746097 to your computer and use it in GitHub Desktop.
Project Euler, no. 84, http://projecteuler.net/problem=84
import random
board = ["GO", "A1", "CC1", "A2", "T1", "R1", "B1", "CH1", "B2", "B3", "JAIL",
"C1", "U1", "C2", "C3", "R2", "D1", "CC2", "D2", "D3", "FP",
"E1", "CH2", "E2", "E3", "R3", "F1", "F2", "U2", "F3", "G2J",
"G1", "G2", "CC3", "G3", "R4", "CH3", "H1", "T2", "H2"]
double_board = board * 2
visits = [0] * len(board)
cc_cards = ["GO", "JAIL"] + ["NOP"] * 14
ch_cards = ["GO", "JAIL", "C1", "E3", "H2", "R1", "R*", "R*", "U*", "-3"] + ["NOP"] * 6
random.shuffle(cc_cards)
random.shuffle(ch_cards)
double_rolls = [0, 0, 0]
def is_double_roll((x, y)):
return x == y
def three_double_rolls():
global double_rolls # :S
go_jail = sum(double_rolls) == 3
if go_jail:
double_rolls = [0, 0, 0]
return go_jail
def two_dice():
double_rolls.pop(0)
dice = (random.randint(1, 6), random.randint(1, 6))
if is_double_roll(dice):
double_rolls.append(1)
else:
double_rolls.append(0)
return dice
def get_next_card(deck):
top = deck.pop(0)
deck.append(top)
return top
def lookup(board_name, current_pos):
return board.index(board_name)
def step(current_pos, step):
return (current_pos + step) % len(board)
def linear_search(from_pos, lead):
pos = from_pos + 1
while not double_board[pos].startswith(lead):
pos += 1
return step(pos, 0)
def card_action(current_pos, card):
if card in board:
return lookup(card, current_pos)
else:
if card == "NOP":
return current_pos
if card == "-3":
return step(current_pos, -3)
return linear_search(current_pos, card[0])
def advance_once(current_pos):
if three_double_rolls():
return lookup("JAIL", current_pos)
if board[current_pos] == "G2J":
return lookup("JAIL", current_pos)
if board[current_pos][:2] == "CC":
return card_action(current_pos, get_next_card(cc_cards))
if board[current_pos][:2] == "CH":
return card_action(current_pos, get_next_card(ch_cards))
return current_pos
def advance(current_pos):
prev = current_pos
next = advance_once(prev)
while next != prev:
prev = next
next = advance_once(prev)
return next
def move(current_pos):
steps = sum(two_dice())
new_pos = step(current_pos, steps)
new_pos = advance(new_pos)
visits[new_pos] += 1
return new_pos
count = 10000
pos = 0
for i in range(count):
pos = move(pos)
probs = [100 * v / float(count) for v in visits]
print probs
print "JAIL (6.24%): {val}".format(val=probs[10])
print "E3 (3.18%): {val}".format(val=probs[24])
print "GO (3.09%): {val}".format(val=probs[0])
print "G2J (0.00%): {val}".format(val=probs[30])
result = list(reversed(sorted(zip(probs, range(0, len(probs))))))
print result
print "".join(map(lambda (x, y): ("00" + str(y))[-2:], result[:3]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment