0

我学校的一位橄榄球教练要求我为即将到来的比赛编写一个有条件的橄榄球比赛平局,任务安排如下:给定一个 1-12 支球队的名单,分成 3 组([Group1 = 1, 2, 3, 4], [Group2 = 5, 6, 7, 8,], [Group3 = 9, 10, 11, 12]) 生成并打印 11 轮循环比赛,条件如下:

  • Group1 中的团队与 Group3 中的团队不同
  • 第 1 组中的球队与第 1 组中的所有其他球队进行两次比赛(例如 1v2、2v1、1v3、3v1、1v4、4v1、1v5、5v1 ......)

    同样的规则适用于 Group3 中的团队,因为他们与 Group3 中的其他团队竞争

  • 第 2 组中的队伍每队每队一次。
  • Group1 和 Group3 中的球队需要一场 Bye Game。

我尝试了多次,但不可避免地被卡住了,以下是我的 2 次尝试:

尝试1:

import operator
import functools
import random



###First Generation (Flawed unclean round robin)
def fixtures(teams):
    if len(teams) % 2:
        teams.append('Day off')  # if team number is odd - use 'day off' as fake team     

    rotation = list(teams)       # copy the list
    random.shuffle(rotation)

    fixtures = []
    for i in range(0, len(teams)-1):
        fixtures.append(rotation)
        rotation = [rotation[0]] + [rotation[-1]] + rotation[1:-1]

    return fixtures

def main():
    # demo code
    teams = ["Team1","Team2","Team3","Team4","Team5","Team6","Team7","Team8","Team9","Team10","Team11","Team12"]
    groupA = ["Team1","Team2","Team3","Team4"]
    groupB = ["Team5","Team6","Team7","Team8"]
    groupC = ["Team9","Team10","Team11","Team12"]

    # for one match each - use this block only
    matches = fixtures(teams)

    print("flawed matches:")
    RoundCounter = 0

    homeTeams = []
    awayTeams = []

    for f in matches:
        #print(f)
        homeTeams = f[::2]
        awayTeams = f[1::2]
        print("Home Teams:{}".format(homeTeams))
        print("Away Teams:{}".format(awayTeams))
        HomeTeamGroupA = set(homeTeams).intersection(groupA)
        HomeTeamGroupC = set(homeTeams).intersection(groupC)
        AwayTeamGroupA = set(awayTeams).intersection(groupA)
        AwayTeamGroupC = set(awayTeams).intersection(groupC)

        VSCounter = 0

        for p, o in zip(homeTeams, awayTeams):
            if p in HomeTeamGroupA:
                if o in AwayTeamGroupC:
                    AvsCPosition = awayTeams.index(o)
                    VSCounter += 1
                    RoundCleanUp(homeTeams, awayTeams, AvsCPosition, VSCounter) #if this is returned begin cleaning the round
                else: print("GroupA is versing either Group B or GroupA") #if this is returned it is a team 1-4 but is vs either group b or group a
            elif p in HomeTeamGroupC:
                if o in AwayTeamGroupA:
                    AvsCPosition = awayTeams.index(o)
                    VSCounter += 1
                    RoundCleanUp(homeTeams, awayTeams, AvsCPosition, VSCounter) #if this is returned begin cleaning the round
                else:
                    print("GroupC is versing either Group B or GroupC")  #if this is returned it is a team 9-12 but is vs either group b or group c
            else:
                pass

def RoundCleanUp(HTeam, ATeam, AvsCPos, VSCounter):
    ##gets Value of List at position
    HTeamVal = HTeam[AvsCPos]
    ATeamVal = ATeam[AvsCPos]
main()

尝试2:

import operator
import functools
import random


def make_round(rotation, num_teams, fixtures):
    for i in range(num_teams - 1):
        rotation = list(range(1, num_teams + 1))
        # clip to 0 .. num_teams - 2 # if i == 0, no rotation is needed (and using -0 as list index will cause problems)
        i %= (num_teams - 1)
        if i:
            rotation = rotation[:1] + rotation[-i:] + rotation[1:-i]
        half = num_teams // 2
        fixtures.append(list(rotation[:half]))
        fixtures.append(list(rotation[half:][::-1]))
    return fixtures


def make_schedule(teams):
    """Produces RoundRobin"""
    # number of teams must be even
    TeamLength = len(teams)
    if TeamLength % 2:
        TeamLength += 1  # add a dummy team for padding

    # build first round-robin
    rotation = list(teams)
    Fixture = []
    schedule = make_round(rotation, TeamLength, Fixture)

    return schedule


def homeAwayRotation(matches):
    for homeTeams, awayTeams in zip(matches[0::2], matches[1::2]):
        print("Home Rotation: {}".format(homeTeams))
        print("Away Rotation: {}".format(awayTeams))
        validation(homeTeams, awayTeams)


def validation(homeTeams, awayTeams):
    groupA = [1, 2, 3, 4]
    groupC = [9, 10, 11, 12]


    for x, y in zip(homeTeams, awayTeams):
        if x in groupA:
            if y in groupC:
                AvsCPosition = awayTeams.index(y)
                cleanDirtyData(homeTeams, awayTeams, AvsCPosition)
            else:
                    # if this is returned it is a team 1-4 but is vs either group b or group a
                print("Group A vsing either itself or GroupB\n")
        elif x in groupC:
            if y in groupA:
                AvsCPosition = awayTeams.index(y)
                cleanDirtyData(homeTeams, awayTeams, AvsCPosition)
            else:
                # if this is returned it is a team 9-12 but is vs either group b or group c
                print("Group C vsing either itself or GroupB\n")
        else:
            # if this is returned it is a team in group B
            print("This is team B\n")


def cleanDirtyData(homeTeams, awayTeams, AvsCPosition):
    HTeamVal = homeTeams[AvsCPosition]
    ATeamVal = awayTeams[AvsCPosition]
    Dirtlist = []
    Dirtlist.append(HTeamVal)
    Dirtlist.append(ATeamVal)
def main():
    # demo code
    teams = ["Team1", "Team2", "Team3", "Team4", "Team5", "Team6",
             "Team7", "Team8", "Team9", "Team10", "Team11", "Team12"]

    # for one match each - use this block only
    matches = make_schedule(teams)

    print("flawed matches:")

    homeAwayRotation(matches)


main()

我的预期结果将是打印每一轮,显示哪个团队正在研究哪个团队,每个团队都有这样的历史:

  • Group1 中的一个团队有以下经文历史:(以任意随机顺序)

    1v2、2v1、1v3、3v1、1v4、4v1、1v5、1v6、1v7、1v8,再见

  • Group2 中的一个团队有以下经文历史:(以任意随机顺序)

    5v1、5v2、5v3、5v4、5v6、5v7、5v8、5v9 5v10、5v11、5v12

  • Group3 中的一个团队有以下经文历史:(以任意随机顺序)

    9v10, 10v9, 9v11, 11v9, 9v12, 12v9, 9v5, 9v6, 9v7, 9v8, 再见

我可能会做的任何指示或改进将不胜感激,因为我在过去 2 周一直被困在最后一个障碍上

4

1 回答 1

0

如果我对问题的理解是正确的,那么您所需要的只是将团队与不同组中的每个成员进行一些组合。

我将一些代码放在一起应该可以解决您的问题:

def vs(team, group):
    matchups = map(lambda opponent: (team,opponent), group)
    matchups = filter(lambda tup: tup[0] != tup[1], matchups)
    return list(matchups)

def matches(teams):
    group_size = len(teams) // 3

    # Make the groups, basically just splitting the team list in three parts
    groups = [teams[:group_size], teams[group_size:2*group_size], teams[2*group_size:]]
    matchups = []
    for index, team in enumerate(teams):
        group_index = index // group_size
        current_matchup = []

        # Check if we're working with group 1 or 3
        if group_index == 0 or group_index == 2:

            # Flip the order of a tuple
            def flip(x):
                return (x[1], x[0])

            own_group = vs(team, groups[group_index])

            # Add matches against everyone in the group
            current_matchup.extend(own_group)

            # Add matches agains everyone in the group again, but now the current team is 'away'
            current_matchup.extend(list(map(flip, own_group)))

            # Add matches against everyone in group 2
            current_matchup.extend(vs(team, groups[1]))

            # Lastly, add the bye 
            current_matchup.append((team, "bye"))
        else:
            # Just all matches against all other teams, once.
            current_matchup.extend(vs(team, teams))
        matchups.append(current_matchup)
    return matchups

# This can be anything. Numbers, 'Team 1' or even 'The wondrous flying squirrels of death'
teams = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
# Make matches
matchups = matches(teams)


# Just pretty print
for i in range(len(matchups)):
    matches = '\n\t'.join(map(lambda m: f'{str(m[0]).rjust(10)} vs {str(m[1]).ljust(10)}', matchups[i]))
    print(f"Team '{teams[i]}' matches:\n\t{matches}")
于 2019-09-09T06:35:19.887 回答