I want to do some Monte Carlo simulations on a system based on a pool of dice. For each trial, a number of dies are rolled, and the winner is the highest value, getting as many points as dice are over the second, including ties.Examples:[1, 2], [5, 1]  One point for the second (5 is the only value over 2).[20, 12, 20, 14], [17, 15, 19, 18] Two points for the first one (two 20 over 19).[20, 12, 20, 14], [17, 15, 20, 18] Two points for the first one (one tie at 20, one die over 18).Here is my algorithm. Can you think of a better way?from collections import Counterimport numpy as npdef check_rolls(one, other):    one_c = Counter(one)    other_c = Counter(other)    ties = Counter()    # Remove ties:    for tie_val in set(one_c.keys()).intersection(other_c.keys()):        toremove = min(one_c[tie_val], other_c[tie_val])        one_c[tie_val] -= toremove        other_c[tie_val] -= toremove        ties[tie_val] = toremove        # Clear if 0        if one_c[tie_val] == 0:            del one_c[tie_val]        if other_c[tie_val] == 0:            del other_c[tie_val]    max_one = max(one_c.keys()) if one_c else 0    max_other = max(other_c.keys()) if other_c else 0    winner = max_one > max_other    threshold = min(max_one, max_other)    if winner:        # One wins        result = sum(val for key, val in one_c.iteritems()                   if key > threshold) + \                   sum(val for key, val in ties.iteritems()                        if key >= threshold)    else:        result = -(sum(val for key, val in other_c.iteritems()                    if key > threshold) +                    sum(val for key, val in ties.iteritems()                        if key >= threshold))    return resultdef roll(d_player, d_gm):    return check_rolls(np.random.randint(1, 21, size=d_player),                       np.random.randint(1, 21, size=d_gm))def test():    assert check_rolls([1, 1, 2], [1, 1]) == 3    assert check_rolls([1, 2, 4, 5], [3, 4]) == 2    assert check_rolls([1, 2, 4, 5], [3, 5]) == 2    assert check_rolls([1, 2, 4, 5], [3, 6]) == -1    assert check_rolls([20, 12, 20, 14], [17, 15, 20, 5, 18, 2]) == 2    assert check_rolls([20, 10, 2, 4], [ 5, 20, 6, 4, 19, 3]) == -2I am just using it for a quick and dirty script plotting histograms for different configurations. Performance improvements are welcomed, but they are not critical. Style and integration are of low priority.
Scoring system of a pool of dice
python;algorithm;random;numpy;simulation
Your code looks rather complicated compared to your description of the game. It would seem to me that using Counter is not a good approach. Instead, we could sort both lists and compare the pairs from the big end untilthere is a difference, which is where we note who the winner is and what the loser's number was, and continue untilthe winner's number is less than what loser's number was at 1.Here's my code that passes your tests. I handle the case of a complete tie differently from you: by returning 0 which feels logical.from itertools import izip_longestdef check_rolls(one, other):    one = sorted(one, reverse=True)     other = sorted(other, reverse=True)     score = 0    zipped = izip_longest(other, one, fillvalue=0)    for a, b in zipped:        score += 1        if a != b:            winner = a < b            losing_number = min(a,b)            break    else:        return 0 #tie    for pair in zipped: #continues iteration where previous loop left off        if pair[winner] >= losing_number:            score += 1        else:            break    return score if winner else -score