これは、 2 人ごとに 1 回だけグループ化するためのグループ化計画は何ですか? のフォローアップの質問です。
基本的に、ラウンドロビンアルゴリズムを実装しました。
このアルゴリズムにより、可能な要素の各ペアが 1 回だけグループ化されたペア リストを生成できます。
たとえば、次のようa, b, c, d
になります。
初日は
a
b
c d
次に、[(a,c);(b,d)] のようにグループ化します。
次に、次のように時計回りに丸めます
a
c
d b
次に、[(a,d);(c,b)] のようにグループ化します。
次に、次のように時計回りに丸めます
a
d
b c
次に、[(a,b);(d,c)] のようにグループ化します。
(注、a
常に固定されています。)
最後に私は得ることができます
[(a,c);(b,d)]
[(a,d);(c,b)]
[(a,b);(d,c)]
ocaml コードは次のとおりです。
let split = List.fold_left (fun (l1, l2) x -> (l2, x::l1)) ([], [])
let round l1 l2 =
match List.rev l1, l2 with
| _, [] | [], _ -> raise Cant_round
| hd1::tl1, hd2::tl2 ->
hd2::(List.rev tl1), List.rev (hd1::List.rev tl2)
let rec robin fixed stopper acc = function
| _, [] | [], _ -> raise Cant_robin
| l1, (hd2::tl2 as l2) ->
if hd2 = stopper then acc
else robin fixed stopper ((List.combine (fixed::l1) l2)::acc) (round l1 l2)
let round_robin = function
| [] | _::[] -> raise Cant_round_robin
| hd::tl ->
let l1, l2 = in
match split tl with
| _, [] -> raise Cant_round_robin
| l1, (hd2::_ as l2) ->
robin hd hd2 ((List.combine (hd::l1) l2)::[]) (round l1 l2)
コードは、アルゴリズムに従って非常に単純です。より良い実装はありますか?