想法来源
最近到了夏季的尾巴了,小shin的公司想来一波运动团建,搞搞羽毛球啊乒乓球之类的比赛,因为报名的人数并不是都是偶数,会出现奇数,有人轮空的情况。
根据赛程承办方,其实就是部门boss的想法,落单的人不轮空,抓对多赛一场,这样一来,为了避免多赛的人心里不平衡,秉承公开公正的原则,有了这次的代码。
思路
- 需要判断报名人数是否可以直接进行淘汰赛制排赛程,也就是人数为2的次幂:2,4,8,16,32…
- 如果多余人数,需要抓对出来,多赛一轮。
使用的库
import math,random
判断
def judge(num):
power=math.log(num,2)
floor=math.floor(power)
flag=0
rest=0
if power-floor==0:
flag=1
rest=0
else:
flag=0
rest=num-(2**floor)
return [flag,floor,rest]
lag: 1 为是2的整次幂,0为不是
floor: 是赛程轮数
rest: 是挑出来多赛一轮的人数
排赛程
def sortgame(personlist1):
personlist=personlist1.copy()
num=len(personlist)
game_sort_list=[]
if num>1 :
re=judge(num)
if re[0]==1:
for i in range(2**(re[1]-1)):
person1=random.choice(personlist)
personlist.remove(person1)
person2=random.choice(personlist)
personlist.remove(person2)
game_sort_list.append(person1+' VS '+person2)
elif re[0]==0:
restmatch=[]
for i in range(re[2]):
person1=random.choice(personlist)
personlist.remove(person1)
person2=random.choice(personlist)
personlist.remove(person2)
restmatch.append('[ '+person1+' VS '+person2+' ]')
for i in restmatch:
person3=random.choice(personlist)
personlist.remove(person3)
game_sort_list.append(i+' VS '+person3)
rest=num-re[2]*3
for i in range(int(rest/2)):
person1=random.choice(personlist)
personlist.remove(person1)
person2=random.choice(personlist)
personlist.remove(person2)
game_sort_list.append(person1+' VS '+person2)
else:
print('only one person!')
return game_sort_list
这里用到choice函数,从list中随机取一人,并使用remove函数移除。
这里返回的值是双方队员拼接的字符串,例如 ‘队员1 vs 队员2’ ,当然,为了便于画图操作,可以修改函数中获得的值的格式。
Demo
male_single=['小明','小红','小鵬','小文','小陳','小徐',
'小奇','小李','小顧','小曹','小斌','小才',
'小周','小洋','小健','小白','小相','小星','小夏']
a=sortgame(male_single)
print(a)
Result
['[ 小白 VS 小星 ] VS 小曹',
'[ 小洋 VS 小李 ] VS 小红',
'[ 小文 VS 小相 ] VS 小周',
'小徐 VS 小顧',
'小斌 VS 小奇',
'小陳 VS 小夏',
'小鵬 VS 小明',
'小才 VS 小健']
如果有更简单的方法请告诉我哦,这里是小shin,欢迎指点,谢谢。