This program has been disqualified.
Author | Sean |
Submission date | 2017-04-06 08:00:16.848568 |
Rating | 6974 |
Matches played | 140 |
Win rate | 71.43 |
if input == "":
import collections
import math
import random
gamma = random.gammavariate
sqrt = math.sqrt
log = math.log
exp = math.exp
moves = R, P, S = 0, 1, 2
index = {"R": R, "P": P, "S": S}
good_against = (P, S, R)
bad_against = (S, R, P)
name = ("R", "P", "S")
def log_add(a, b):
if a > b:
a, b = b, a
return a + log(1+exp(b-a))
log_half = log(0.5)
def log_mean(a, b):
return log_add(a, b) + log_half
def belief(counts):
counts = [random.gammavariate(n + 0.5, 1) for n in counts]
t = sum(counts)
return [n / t for n in counts]
class CTW:
def __init__(self):
self.counts = [0.5] * 3
self.children = None
self.p_self = 0
self.p_children = 0
self.p = 0
def update(self, h):
s = h[-1]
i = len(h) - 2
d = 0
self.update_helper(s, h, i, d)
def update_helper(self, x, h, i, d):
p_cond = log(self.counts[x] / sum(self.counts))
self.p_self += p_cond
self.counts[x] += 1
if i < 0 or d >= 10:
self.p = self.p_self
return
if self.children is None:
self.children = tuple(CTW() for _ in range(3))
self.p_children = self.p_self
child = self.children[h[i]]
self.p_children -= child.p
child.update_helper(x, h, i - 1, d + 1)
self.p_children += child.p
self.p = log_mean(self.p_self, self.p_children)
def predict(self, h):
i = len(h) - 1
d = 0
p = [exp(self.predict_helper(m, h, i, d) - self.p) for m in moves]
scores = [p[bad_against[m]] - p[good_against[m]] for m in moves]
s = max(scores)
return random.choice([m for m in moves if scores[m] == s])
def predict_helper(self, m, h, i, d):
p_cond = log(self.counts[m] / sum(self.counts))
p_self = self.p_self + p_cond
if i < 0 or d >= 10:
return p_self
if self.children is None:
return p_self
child = self.children[h[i]]
p_children = self.p_children - child.p
p_children += child.predict_helper(m, h, i - 1, d + 1)
return log_mean(p_self, p_children)
class Markov:
def __init__(self):
self.seen = None
self.children = None
def update(self, h):
s = h[-1]
i = len(h) - 2
d = 0
while d < 10:
self.seen = s
if self.children is None:
self.children = tuple(Markov() for _ in range(3))
if i < 0:
return
self = self.children[h[i]]
i -= 1
d += 1
def predict(self, h):
i = len(h) - 1
while self.seen is not None:
seen = self.seen
self = self.children[h[i]]
i -= 1
return seen
class Frequency:
def __init__(self, k=1):
self.k=k
self.counts = [0, 0, 0]
def update(self, h):
self.counts[h[-1]] += 1
for i, _ in enumerate(self.counts):
self.counts[i] *= self.k
def predict(self, h):
p = belief(self.counts)
scores = [p[bad_against[m]] - p[good_against[m]] for m in moves]
return scores.index(max(scores))
class Meta:
def __init__(self, predictor):
self.predictor = predictor
self.prediction = None
self.counts = [[0 for _ in range(3)] for _ in range(3)]
def update(self, h):
s = h[-1]
if self.prediction is not None:
for i, counts in enumerate(self.counts):
m = (self.prediction + i) % 3
if m == good_against[s]:
counts[2] += 1
elif m == bad_against[s]:
counts[0] += 1
else:
counts[1] += 1
self.predictor.update(h)
def predictions(self, h):
self.prediction = self.predictor.predict(h)
for i, counts in enumerate(self.counts):
p = belief(counts)
yield ((self.prediction + i) % 3, p[2] - p[0])
class Random:
def __init__(self):
pass
def update(self, h):
pass
def predictions(self, h):
return [(random.choice(moves), 0)]
class PredictionBlender:
def __init__(self, predictors):
self.predictors = predictors
def update(self, h):
for predictor in self.predictors:
predictor.update(h)
def predict(self, h):
predictions = [p for predictor in self.predictors for p in predictor.predictions(h)]
best_score = float('-inf')
for m, score in predictions:
if score > best_score:
move = m
best_score = score
return move
predictors = [
Meta(Markov()),
Meta(Frequency()),
Meta(Frequency(k=0.99)),
Meta(Frequency(k=0.9)),
Meta(Frequency(k=0.8)),
Meta(Frequency(k=0.5)),
Meta(CTW()),
Random()
]
model = PredictionBlender(predictors)
history = []
output = random.choice(name)
else:
us = index[output]
them = index[input]
history.append(them)
model.update(history)
history.append(us)
output = name[model.predict(history)]