#!/usr/bin/python3

_cache = {}
def sums(addends, sum):
    """Return list of tuples of @addends addends that sums up to @sum."""
    global _cache
    if addends < 1 or sum < addends:
        return []
    if (addends, sum) not in _cache:
        result = [] if addends > 1 else [(sum,)]
        for d in reversed(range(1, sum)):            
            result.extend([(d,) + a for a in sums(addends-1, sum-d) if len(a) == 0 or d >= a[0]])
        _cache[addends, sum] = result
    return _cache[addends, sum]
    
def compare(dieA, dieB):
    """Return sum over all possible die game results.
    Die A wins: +1, die B wins -1, tie: 0."""
    return sum([1 if a > b else -1 for a in dieA for b in dieB if a != b])



def iterate():
    """Return the best die for me if opponent has die X with given probability (distribution[X]).
    Then update distribution to linear (0: worst die, max: best die (max chosen in such a way that probs add up to one))
     or uniformly choose k-best dice."""
    global dice, distribution, score
    score = {}
    for myDie in dice:
        score[myDie] = 0
        for otherDie in dice:
            score[myDie] += compare(myDie, otherDie) * distribution[otherDie]
    dice = sorted(dice, key=lambda die: score[die], reverse=True)
    #distribution = {die: 2*i/len(dice)**2 for i, die in enumerate(reversed(dice), 1)}
    best = 3
    distribution = {die: 1/best if die in dice[:best] else 0 for i, die in enumerate(reversed(dice), 1)}
    
def reportAll():
    global score, dice
    for die in dice:
        print("{}\t{}\t".format(die, score[die]), distribution[die])

# initialize to uniform distribution
dice = sums(6, 27)
distribution = {die: 1/len(dice) for die in dice}
score = {die: 0 for die in dice}

# iterate and print best die
for _ in range(20):
    die = dice[0]
    print("{}\t{}\t".format(die, score[die]), distribution[die])
    iterate()