基本上,我实现了循环算法。
通过该算法,它可以生成对列表,其中每个可能的元素对恰好组合在一起一次。
例如,我们有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)
遵循算法,代码非常简单。有更好的实现吗?