This paste expires on 2023-04-16 20:33:37.477599. Repaste, or download this paste. . Pasted through v1-api.

import math
import random
# make random results consistent between runs
random.seed(42)
def generate_players(n_players, min_rank, max_rank):
    ndigits = int(math.log10(n_players)) + 1
    return [(f"Player{N:0{ndigits}d}", random.randint(min_rank, max_rank)) for N in range(n_players)]
def sort_players(player_list):
    # the `key` here means we will sort using the rank value
    # the result is a list of players from low to high ranks
    return sorted(player_list, key=lambda pair: pair[1])
def rank_diffs(left, mid, right):
    right_diff = abs(right[1] - mid[1])
    if left:
        left_diff = abs(left[1] - mid[1])
    else:
        # there is no left player, which we can treat as an infinite distance
        left_diff = float('inf')
    return left_diff, right_diff
def match_triplet(left, mid, right, max_rank_diff):
    left_diff, right_diff = rank_diffs(left, mid, right)
    #
    #  |---|       |---|       |---|
    #  | L | ----- | M | ----- | R |
    #  |---|   |   |---|   |   |---|
    #          |           |
    #      left_diff   right_diff
    if left_diff < right_diff:
        lo = left
        hi = mid
        diff = left_diff
    else:
        # left_diff >= right_diff
        # right player wins the tie when left_diff == right_diff
        lo = mid
        hi = right
        diff = right_diff
    #
    #  |----|       |----|
    #  | lo | ----- | hi |
    #  |----|   |   |----|
    #           |
    #          diff
    if diff <= max_rank_diff:
        match = (lo, hi)
    else:
        match = None
    return match, right_diff
def match_players(player_list, max_rank_diff=50):
    players = player_list.copy()
    matches = []
    while len(players) >= 2:
        right = players.pop()
        mid = players.pop()
        if players:
            # if there are at least three players in the list, we need to look
            # on either side of the 'middle' player
            left = players.pop()
        else:
            # we're looking at the last two players in this list
            left = None
        match, right_diff = match_triplet(left, mid, right, max_rank_diff=max_rank_diff)
        if match == (left, mid):
            if right_diff <= max_rank_diff:
                # right player still might match someone, put them back in the pool
                players.append(right)
            else:
                matches.append((right, None))
        elif match == (mid, right) or match is None:
            players.append(left)
        else:
            # sanity check: (left, right) match shouldn't be possible
            raise RuntimeError("Unexpected match")
        if match:
            matches.append(match)
        else:
            matches.extend([
                (mid, None),
                (right, None)
            ])
    return matches
if __name__ == "__main__":
    print("generating players")
    unsorted_players = generate_players(25, min_rank=1000, max_rank=2000)
#     unsorted_players = [
#         ("Player1", 2000),
#         ("Player2", 2015),
#         ("Player3", 2020),
#         ("Player4", 2030),
#     ]
    print("unsorted players:")
    print(unsorted_players)
    print("---\n")
    print("sorting players")
    sorted_players = sort_players(unsorted_players)
    print("sorted players:")
    print(sorted_players)
    print("---\n")
    print("creating match pairs")
    matches = match_players(sorted_players)
    for left_player, right_player in matches:
        if right_player is None:
            print(f"{left_player!r} is unmatched")
        else:
            left_rank = left_player[1]
            right_rank = right_player[1]
            rank_diff = abs(left_rank - right_rank)
            print(f"{left_player!r} plays {right_player!r} (rank difference is {rank_diff})")
Filename: theWhisper_.py. Size: 4kb. View raw, , hex, or download this file.
$ python3 theWhisper_.py
generating players
unsorted players:
[('Player00', 1654), ('Player01', 1114), ('Player02', 1025), ('Player03', 1759), ('Player04', 1281), ('Player05', 1250), ('Player06', 1228), ('Player07', 1142), ('Player08', 1754), ('Player09', 1104), ('Player10', 1692), ('Player11', 1758), ('Player12', 1913), ('Player13', 1558), ('Player14', 1089), ('Player15', 1604), ('Player16', 1432), ('Player17', 1032), ('Player18', 1030), ('Player19', 1095), ('Player20', 1223), ('Player21', 1238), ('Player22', 1517), ('Player23', 1616), ('Player24', 1027)]
---
sorting players
sorted players:
[('Player02', 1025), ('Player24', 1027), ('Player18', 1030), ('Player17', 1032), ('Player14', 1089), ('Player19', 1095), ('Player09', 1104), ('Player01', 1114), ('Player07', 1142), ('Player20', 1223), ('Player06', 1228), ('Player21', 1238), ('Player05', 1250), ('Player04', 1281), ('Player16', 1432), ('Player22', 1517), ('Player13', 1558), ('Player15', 1604), ('Player23', 1616), ('Player00', 1654), ('Player10', 1692), ('Player08', 1754), ('Player11', 1758), ('Player03', 1759), ('Player12', 1913)]
---
creating match pairs
('Player12', 1913) is unmatched
('Player11', 1758) plays ('Player03', 1759) (rank difference is 1)
('Player08', 1754) is unmatched
('Player00', 1654) plays ('Player10', 1692) (rank difference is 38)
('Player15', 1604) plays ('Player23', 1616) (rank difference is 12)
('Player22', 1517) plays ('Player13', 1558) (rank difference is 41)
('Player16', 1432) is unmatched
('Player05', 1250) plays ('Player04', 1281) (rank difference is 31)
('Player20', 1223) plays ('Player06', 1228) (rank difference is 5)
('Player21', 1238) is unmatched
('Player01', 1114) plays ('Player07', 1142) (rank difference is 28)
('Player14', 1089) plays ('Player19', 1095) (rank difference is 6)
('Player09', 1104) is unmatched
('Player18', 1030) plays ('Player17', 1032) (rank difference is 2)
('Player02', 1025) plays ('Player24', 1027) (rank difference is 2)
Filename: out.txt. Size: 2kb. View raw, , hex, or download this file.