from collections import Counter
from random import randint
from matplotlib import pyplot
def call_counter(func):
def helper(*args, **kwargs):
helper.calls += 1
return func(*args, **kwargs)
helper.calls = 0
return helper
def random_guess(options):
res = []
for num_options in options:
res.append(randint(0, num_options))
return res
@call_counter
def correct_answers(guess, solution):
correct = 0
for g, s in zip(guess, solution):
if g == s:
correct += 1
return correct
def play_game(possible_responses, solution, strategy):
correct_answers.calls = 0
strategy(possible_responses, solution)
return correct_answers.calls
def xurdones_strategy(possible_responses, solution):
guess = random_guess(possible_responses)
change_idx = 0
old_correct = correct_answers(guess, solution)
while old_correct != len(solution):
old_guess = guess[change_idx]
guess[change_idx] = (guess[change_idx] + 1) % (possible_responses[change_idx]+1)
new_correct = correct_answers(guess, solution)
if new_correct < old_correct:
guess[change_idx] = old_guess
elif new_correct > old_correct:
old_correct = new_correct
if new_correct != old_correct:
change_idx += 1
def random_strategy(possible_responses, solution):
while correct_answers(random_guess(possible_responses), solution) != len(solution):
pass
def run_tests(n):
possible_responses = [1, 2, 1, 2, 1, 2]
solution = [0, 2, 0, 1, 1, 0]
figure = pyplot.figure()
# My strategy
num_rounds_xur = []
num_rounds_rand = []
for _ in range(n):
num_rounds_xur.append(play_game(possible_responses, solution, xurdones_strategy))
num_rounds_rand.append(play_game(possible_responses, solution, random_strategy))
print(Counter(num_rounds_xur))
print(Counter(num_rounds_rand))
ax1 = figure.add_subplot(211)
ax1.hist(num_rounds_xur)
ax2 = figure.add_subplot(212)
ax2.hist(num_rounds_rand)
pyplot.show()
if __name__ == '__main__':
run_tests(1000000)
ZnJvbSBjb2xsZWN0aW9ucyBpbXBvcnQgQ291bnRlcgpmcm9tIHJhbmRvbSBpbXBvcnQgcmFuZGludApmcm9tIG1hdHBsb3RsaWIgaW1wb3J0IHB5cGxvdAoKCmRlZiBjYWxsX2NvdW50ZXIoZnVuYyk6CiAgICBkZWYgaGVscGVyKCphcmdzLCAqKmt3YXJncyk6CiAgICAgICAgaGVscGVyLmNhbGxzICs9IDEKICAgICAgICByZXR1cm4gZnVuYygqYXJncywgKiprd2FyZ3MpCiAgICBoZWxwZXIuY2FsbHMgPSAwCiAgICByZXR1cm4gaGVscGVyCgoKZGVmIHJhbmRvbV9ndWVzcyhvcHRpb25zKToKICAgIHJlcyA9IFtdCgogICAgZm9yIG51bV9vcHRpb25zIGluIG9wdGlvbnM6CiAgICAgICAgcmVzLmFwcGVuZChyYW5kaW50KDAsIG51bV9vcHRpb25zKSkKCiAgICByZXR1cm4gcmVzCgoKQGNhbGxfY291bnRlcgpkZWYgY29ycmVjdF9hbnN3ZXJzKGd1ZXNzLCBzb2x1dGlvbik6CiAgICBjb3JyZWN0ID0gMAogICAgZm9yIGcsIHMgaW4gemlwKGd1ZXNzLCBzb2x1dGlvbik6CiAgICAgICAgaWYgZyA9PSBzOgogICAgICAgICAgICBjb3JyZWN0ICs9IDEKICAgIHJldHVybiBjb3JyZWN0CgoKZGVmIHBsYXlfZ2FtZShwb3NzaWJsZV9yZXNwb25zZXMsIHNvbHV0aW9uLCBzdHJhdGVneSk6CiAgICBjb3JyZWN0X2Fuc3dlcnMuY2FsbHMgPSAwCiAgICBzdHJhdGVneShwb3NzaWJsZV9yZXNwb25zZXMsIHNvbHV0aW9uKQogICAgcmV0dXJuIGNvcnJlY3RfYW5zd2Vycy5jYWxscwoKCmRlZiB4dXJkb25lc19zdHJhdGVneShwb3NzaWJsZV9yZXNwb25zZXMsIHNvbHV0aW9uKToKICAgIGd1ZXNzID0gcmFuZG9tX2d1ZXNzKHBvc3NpYmxlX3Jlc3BvbnNlcykKICAgIGNoYW5nZV9pZHggPSAwCiAgICBvbGRfY29ycmVjdCA9IGNvcnJlY3RfYW5zd2VycyhndWVzcywgc29sdXRpb24pCiAgICB3aGlsZSBvbGRfY29ycmVjdCAhPSBsZW4oc29sdXRpb24pOgogICAgICAgIG9sZF9ndWVzcyA9IGd1ZXNzW2NoYW5nZV9pZHhdCiAgICAgICAgZ3Vlc3NbY2hhbmdlX2lkeF0gPSAoZ3Vlc3NbY2hhbmdlX2lkeF0gKyAxKSAlIChwb3NzaWJsZV9yZXNwb25zZXNbY2hhbmdlX2lkeF0rMSkKICAgICAgICBuZXdfY29ycmVjdCA9IGNvcnJlY3RfYW5zd2VycyhndWVzcywgc29sdXRpb24pCgogICAgICAgIGlmIG5ld19jb3JyZWN0IDwgb2xkX2NvcnJlY3Q6CiAgICAgICAgICAgIGd1ZXNzW2NoYW5nZV9pZHhdID0gb2xkX2d1ZXNzCiAgICAgICAgZWxpZiBuZXdfY29ycmVjdCA+IG9sZF9jb3JyZWN0OgogICAgICAgICAgICBvbGRfY29ycmVjdCA9IG5ld19jb3JyZWN0CiAgICAgICAgaWYgbmV3X2NvcnJlY3QgIT0gb2xkX2NvcnJlY3Q6CiAgICAgICAgICAgIGNoYW5nZV9pZHggKz0gMQoKCmRlZiByYW5kb21fc3RyYXRlZ3kocG9zc2libGVfcmVzcG9uc2VzLCBzb2x1dGlvbik6CiAgICB3aGlsZSBjb3JyZWN0X2Fuc3dlcnMocmFuZG9tX2d1ZXNzKHBvc3NpYmxlX3Jlc3BvbnNlcyksIHNvbHV0aW9uKSAhPSBsZW4oc29sdXRpb24pOgogICAgICAgIHBhc3MKCgpkZWYgcnVuX3Rlc3RzKG4pOgogICAgcG9zc2libGVfcmVzcG9uc2VzID0gWzEsIDIsIDEsIDIsIDEsIDJdCiAgICBzb2x1dGlvbiA9IFswLCAyLCAwLCAxLCAxLCAwXQoKICAgIGZpZ3VyZSA9IHB5cGxvdC5maWd1cmUoKQoKICAgICMgTXkgc3RyYXRlZ3kKICAgIG51bV9yb3VuZHNfeHVyID0gW10KICAgIG51bV9yb3VuZHNfcmFuZCA9IFtdCiAgICBmb3IgXyBpbiByYW5nZShuKToKICAgICAgICBudW1fcm91bmRzX3h1ci5hcHBlbmQocGxheV9nYW1lKHBvc3NpYmxlX3Jlc3BvbnNlcywgc29sdXRpb24sIHh1cmRvbmVzX3N0cmF0ZWd5KSkKICAgICAgICBudW1fcm91bmRzX3JhbmQuYXBwZW5kKHBsYXlfZ2FtZShwb3NzaWJsZV9yZXNwb25zZXMsIHNvbHV0aW9uLCByYW5kb21fc3RyYXRlZ3kpKQogICAgcHJpbnQoQ291bnRlcihudW1fcm91bmRzX3h1cikpCiAgICBwcmludChDb3VudGVyKG51bV9yb3VuZHNfcmFuZCkpCgogICAgYXgxID0gZmlndXJlLmFkZF9zdWJwbG90KDIxMSkKICAgIGF4MS5oaXN0KG51bV9yb3VuZHNfeHVyKQoKICAgIGF4MiA9IGZpZ3VyZS5hZGRfc3VicGxvdCgyMTIpCiAgICBheDIuaGlzdChudW1fcm91bmRzX3JhbmQpCiAgICBweXBsb3Quc2hvdygpCgoKaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKICAgIHJ1bl90ZXN0cygxMDAwMDAwKQo=