Simple use of go random number rand, annual meeting event points schedule setting, group stage battle order

background

The company's annual meeting held activities, and I organized a table tennis match because there were not many people and time was tight. The first round adopts a group points competition system. Everyone in the group will play against each other once. The program implements the order of fighting.

gorandom numberrand

goThe math/randpackage implements a pseudo-random number generator.
The following example generates 10random numbers within rand.Intn:

func tMathRand() {
    
    
	for i := 0; i < 100; i++ {
    
    
		fmt.Println(rand.Intn(10))
	}
}

No matter how many times it is run, the generated results are as follows:

1
7
7
9
1
8
5
0
6
0

This is because the random number seed is not set. Generally speaking, the current timestamp can be used as the random number seed, as follows rand.Seed:

func tMathRand() {
    
    
	rand.Seed(time.Now().Unix())
	for i := 0; i < 100; i++ {
    
    
		fmt.Println(rand.Intn(10))
	}
}

Program to implement points schedule

package main

import (
	"errors"
	"fmt"
	"math/rand"
	"strings"
	"time"
)

func main() {
    
    
	fmt.Println("请输入需要参赛的队伍,用英文逗号 ',' 分隔")
	var peopleStr string
	for {
    
    
		_, err := fmt.Scanf("%s", &peopleStr)
		if err != nil {
    
    
			fmt.Println("输入有误,请重新输入:", err)
			continue
		}
		break
	}

	p := strings.Split(peopleStr, ",")
	res, err := pingpongRand(p)
	if err != nil {
    
    
		fmt.Println(err.Error())
	} else {
    
    
		fmt.Println(res)
	}

	fmt.Println()
	fmt.Println("请输入任意值退出...")

	fmt.Scan(&peopleStr)
	//fmt.Scanln(&peopleStr)
}

type peopleRand struct {
    
    
	Count        int   // 已出现的次数
	MatchedIndex []int // 匹配过的人 下标
}

func (p *peopleRand) Matched(index int) bool {
    
    
	for _, v := range p.MatchedIndex {
    
    
		if v == index {
    
    
			return true
		}
	}
	return false
}

// 输入参赛选手,输出对战信息
func pingpongRand(people []string) ([][]string, error) {
    
    
	rand.Seed(time.Now().Unix())
	peopleLength := len(people)
	if peopleLength <2 {
    
    
		return [][]string{
    
    }, errors.New("参赛至少为 2 组")
	}

	resLength := (peopleLength - 1) * peopleLength / 2
	res := make([][]string, 0, resLength)

	peopleCount := peopleLength - 1 // 1 个人最多出现的次数

	var displayCount = make(map[int]*peopleRand) // 每个人出现的次数
	for {
    
    
		i1 := rand.Intn(peopleLength) // 人员下标
		_, ok := displayCount[i1]
		if !ok {
    
    
			p := new(peopleRand)
			p.Count = 1
			displayCount[i1] = p
		}
		if displayCount[i1].Count > peopleCount {
    
    
			continue
		}
		displayCount[i1].Count++
		couple := make([]string, 2) // 存放对战人名单
		// 判断 i1 已出现的次数
		couple[0] = people[i1]

		for {
    
    
			i2 := rand.Intn(peopleLength)
			if i2 == i1 {
    
     // 剔除自己
				continue
			}
			_, ok := displayCount[i2]
			if !ok {
    
    
				p2 := new(peopleRand)
				p2.Count = 1
				displayCount[i2] = p2
			}
			if displayCount[i2].Count > peopleCount {
    
    
				continue
			}
			// 剔除已匹配过的
			if displayCount[i1].Matched(i2) {
    
    
				continue
			}

			displayCount[i2].Count++
			displayCount[i2].MatchedIndex = append(displayCount[i2].MatchedIndex, i1)
			displayCount[i1].MatchedIndex = append(displayCount[i1].MatchedIndex, i2)
			couple[1] = people[i2]
			break
		}

		res = append(res, couple)
		if len(res) == resLength {
    
    
			break
		}
	}

	return res, nil
}

The output is as follows:
Insert image description here

Summarize

When I first started allocating the schedule, I made a table myself, which felt a bit stupid. . . The code is more convenient.
Insert image description here

Guess you like

Origin blog.csdn.net/DisMisPres/article/details/122350348