from pprint import pprint from collections import defaultdict # Number of stats STATS = 7 # Max SV value MAX_SV = 50 # Minimum total SVs MIN_TOTAL_SVS = 168 def calc_distribution(): # distribution[(n, k)] = number of ways to get total svs n with exactly k perfect svs distribution = {(0, 0): 1} for stat in range(STATS): new_distribution = defaultdict(int) for sv_sum, num_perfect in distribution: for sv in range(1, MAX_SV+1): new_sum = sv_sum + sv new_perfect = num_perfect + (sv == MAX_SV) new_distribution[new_sum, new_perfect] += distribution[sv_sum, num_perfect] distribution = new_distribution return distribution # Reduce on perfect_sv count given that sv_sum >= min_sv_sum # Returns map of perfect_svs -> number of ways that this can be generated. def reduce_distribution(d, min_sv_sum): distribution = defaultdict(int) for sv_sum, num_perfect in d: if sv_sum < min_sv_sum: continue distribution[num_perfect] += d[sv_sum, num_perfect] return distribution def main(): distribution = calc_distribution() x = reduce_distribution(distribution, MIN_TOTAL_SVS) pprint(dict(x)) print "Total: %d" % sum(x.values()) print "Probability of 1+ perfect SV: %f" % (float(sum(x.values()) - x[0]) / sum(x.values())) if __name__ == '__main__': main()