This program has been disqualified.
Author | Sean |
Submission date | 2016-04-28 16:44:19.501125 |
Rating | 6781 |
Matches played | 76 |
Win rate | 72.37 |
if input == "":
import array
import math
log = math.log
exp = math.exp
log_half = log(1/2.0)
log_third = log(1/3.0)
log_sixth = log(1/6.0)
log_p_self0 = log(1) - log(3)
def safe_exp(x):
if x <= -100:
return 0
if x >= 100:
return float("inf")
return exp(x)
def log_add(x, y):
if y > x:
x, y = y, x
d = y - x
if d < -20:
return x
return x + log(1.0 + exp(d))
def smooth(counts, x):
y = random.gammavariate(counts[x] + 0.5, 1)
return log(y) - log(sum(counts) + 0.5 * len(counts))
def predict_leaf(n, i):
if i >= len(history) - 1 or i >= 16:
return log_p_self0
return log_add(log_p_self0, predict_leaf(history, i+1)) + log_half
class ContextTree:
def __init__(self, n=3):
self.log_p_self = 0.0
self.log_p = 0.0
self.counts = array.array('i',(0 for _ in xrange(n)))
self.total = 0
self.children = None
def update(self, history, i=0):
x = history[i]
if x >= len(self.counts):
x -= 3
self.log_p_self += smooth(self.counts, x)
self.total += 1
self.counts[x] += 1
if i >= len(history) - 1 or i >= 16:
self.log_p = self.log_p_self
return
if self.children is None:
self.children = [None for _ in xrange(len(self.counts))]
if self.children[x] is None:
self.children[x] = ContextTree()
self.children[x].update(history, i + 1)
log_p_children = 0
for child in self.children:
if child is not None:
log_p_children += child.log_p
self.log_p = log_add(self.log_p_self, log_p_children) + log_half
def predict(self, history, i=0):
x = history[i]
if x >= len(self.counts):
x -= 3
log_p_self = self.log_p_self + smooth(self.counts, x)
if i >= len(history) - 1 or i >= 16:
return log_p_self
if self.children is None or self.children[x] is None:
log_p_children = predict_leaf(history, i + 1)
else:
log_p_children = self.children[x].predict(history, i + 1)
if self.children is not None:
for y, child in enumerate(self.children):
if child is not None and x != y:
log_p_children += child.log_p
return log_add(log_p_self, log_p_children) + log_half
import collections
import random
R, P, S = 0, 1, 2
index = {"R": R, "P": P, "S": S}
name = ("R", "P", "S")
beat = (P, S, R)
beaten = (S, R, P)
model = ContextTree(6)
history = collections.deque([])
output = random.choice(name)
counts = [0, 0, 0]
round_number = 1
else:
i = index[input]
j = index[output]
counts[i] += 1
history.appendleft(i)
model.update(history)
history.appendleft(j + 3)
model.update(history)
log_ps = [0.0, 0.0, 0.0]
log_t = float("-inf")
for i in xrange(3):
history.appendleft(i)
log_p = model.predict(history)
history.popleft()
log_t = log_add(log_t, log_p)
log_ps[i] = log_p
ps = [safe_exp(log_p - log_t) for log_p in log_ps]
total = sum(ps)
scores = [0, 0, 0]
for i in xrange(6):
r = random.uniform(0, total)
t = 0
for j in xrange(round_number):
t += ps[j]
if t >= r:
break
scores[beat[j]] += 1
scores[beaten[j]] -= 1
best = max(scores)
output = name[random.choice([i for i in xrange(3) if scores[i] == best])]
round_number += 1