-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscheduledLeague.fsx
More file actions
58 lines (53 loc) · 2.47 KB
/
scheduledLeague.fsx
File metadata and controls
58 lines (53 loc) · 2.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
(*
試合方法 総当り
出場チーム数 13チーム
一度で同時に行える試合数(コートの面数) 5試合
この条件にて、5面のコートをA、B、C、D、E とした時
全78試合の行われる組み合わせを列挙せよ。
*)
let scheduledLeague matchCount teamCount =
if teamCount <= 0 then invalidArg "teamCount" "正の数を入力してください"
if matchCount <= 0 then invalidArg "matchCount" "正の数を入力してください"
let league teams =
let rotate teams =
let len = Array.length teams
teams |> Array.permute (function
| i when i = len - 1 -> i
| i -> (i + 1) % (len - 1))
let pairwise teams =
let len = Array.length teams
[ for i in 0 .. len / 2 - 1 do
match teams.[i], teams.[len - 1 - i] with
| Some x, Some y -> yield [x; y]
| _ -> () ]
let teams =
[| for team in teams do yield Some team
if List.length teams % 2 = 1 then yield None |]
(Array.length teams - 1, teams) |> Seq.unfold (function
| 0, _ -> None
| i, ts -> Some(pairwise ts, (i - 1, rotate ts)))
|> Seq.toList
let schedule matchCount allLeagueMatches =
let partition count teams =
let now = teams |> Seq.truncate count |> Seq.toList
let next = teams |> Seq.skip (List.length now) |> Seq.toList
now, next
allLeagueMatches |> Seq.unfold (function
| [] | []::[] -> None
| ts::rest when List.length ts >= matchCount ->
let (now, next) = partition matchCount ts
Some(now, next::rest)
| ts::[] -> Some(ts, [])
| ts1::ts2::rest ->
let (available, unavailable) =
ts2 |> List.partition (List.forall (fun t -> ts1 |> List.forall (List.forall ((<>) t))))
let (now, next) = available |> partition (matchCount - List.length ts1)
Some(ts1 @ now, (next @ unavailable)::rest))
|> Seq.toList
let print allLeagueMatches =
allLeagueMatches |> List.iteri (fun i ts ->
printfn "第%d回目" <| i + 1
ts |> Seq.map (Seq.map string >> String.concat "-")
|> Seq.zip (Seq.init matchCount ((+) (int 'A') >> char))
|> Seq.iter ((<||) (printfn "%c %s")))
[1 .. teamCount] |> league |> schedule matchCount |> print