#!/etc/python3.5 from math import factorial class PoolRoll: def __init__( self, poolroll, newdieroll ): self.roll = poolroll.roll[:] self.roll[newdieroll] += 1 self.count = poolroll.count def __eq__(self, other): return not cmp(self.roll,other.roll) def __hash__(self): total = 0 for i in xrange(2,13): total += self.roll[i] * i return (total) class Pool: def __init__(self, oldpool, currentpool): dierolls = (0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) self.pool = currentpool[:] self.rolls = {} for oldpoolroll in oldpool.rolls: for dieroll in dierolls: if dieroll <= currentpool[-1]: newpoolroll = PoolRoll(oldpool.rolls[oldpoolroll], dieroll, ) if str(newpoolroll.roll) in self.rolls: self.rolls[str(newpoolroll.roll)].count += newpoolroll.count else: self.rolls[str(newpoolroll.roll)] = newpoolroll class SeedRoll: def __init__( self, die ): self.roll = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] self.roll[die] += 1 self.count = 1 def __cmp__(self, other): return not cmp(self.roll,other.roll) def __eq__(self, other): return not cmp(self.roll,other.roll) def __hash__(self): total = 0 for i in xrange(2,13): total += self.roll[i] * i return (total) class SeedPool: def __init__(self, die): dierolls = (0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) self.pool = [die] self.rolls = {} for roll in dierolls: if roll <= die: seed = SeedRoll(roll) seedkey = [roll] self.rolls[str(seedkey)] = seed def successes(self): return([[die, 0, 0, 0, 0, 0]]*14) #poolrolls{str(roll):roll[]} def successes(poolrolls, TN): def cycle( roll, TN ): def rolltotal(roll): total = 0 for i in xrange(2,13): total += roll[i] * i return total def newlarge(roll): x = 12 while x > 0: if roll[x]: return x else: x += -1 return 0 def newsmall(roll): x=2 #[0] and [1] will always be 0 while x < 13: if roll[x]: return x else: x += 1 return 0 #cycle rollsum = rolltotal(roll) if rollsum < TN: return 0 elif rollsum < 2 * TN: return 1 else: large = newlarge(roll) if roll[ TN - large ]: roll[ TN - large ] += -1 roll[large] += -1 return 1 + cycle( roll, TN ) else: total = large roll[large] += -1 while total < TN: small = newsmall(roll) total += small roll[small] += -1 return 1 + cycle( roll, TN ) #successes(poolrolls, TN): rolls = poolrolls totals = [0, 0, 0, 0, 0, 0] for roll in rolls: totals[cycle(rolls[roll].roll[:], TN)] += rolls[roll].count return(totals) #pools{st(pool):rolls{str(roll):roll[]} } def iterate( pools, oldpool, lastpool, MAX ): dice = (4, 6, 8, 10, 12) pools[str(lastpool)] = oldpool if len(lastpool) == MAX: success = [] file = open("iterative additive.2", "a") keylist = [key for key in pools if pools[key].pool[-1] == lastpool[-1]] for key in keylist: for TN in xrange(5,14): if max(pools[key].pool) < TN: success = successes(pools[key].rolls,TN) file.write("%d %s %s\n" % ( (TN-1), key, success)) del pools[key] file.close() return() else: for newdie in dice: currentpool = lastpool[:] if newdie <= lastpool[-1]: currentpool.append(newdie) print currentpool pool = Pool(oldpool, currentpool) iterate( pools, pool, currentpool, MAX ) #main MAX = 11 dice = (4, 6, 8, 10, 12) for die in dice: currentpool = [die] seed = SeedPool(die) pools = {} iterate(pools, seed, currentpool, MAX) del pools, seed