0-9 共 10 个数字,分为 5 组(每组两个数字,小到大排列),要求后一组数字大于前一组数字,生成像 01-23-45-67-89 这样的组合,列出所有的组合。
-_-#又来一个……其实可以放一起讨论吧……
(0..9).to_a.permutation.map {|a|
a.each_slice(2).map {|x| x.sort.join}
} .select {|a|
a.each_cons(2).all? {|x, y| x < y }
}.uniq
效率就……不要想了……
……刚才漏看个条件……
后一组比前一组大,是指两个数字的 sum 大,还是挨个比较大 (第一个大第二个就忽略了),还是全部大 (第一个和第二个都大)? 如何是和的话,组合就相当相当的多了。
假设都 2 个都必须大:
:m Data.List
let pairs = [(a,b) | a <- [0..9], b <- [0..9], a < b]
let result = [(x,y,z,m,n) | x <- pairs, y <- pairs, z <- pairs, m <- pairs, n <- pairs,
(\(h,t) (p,q) -> (h < p && t < q)) x y,
(\(h,t) (p,q) -> (h < p && t < q)) y z,
(\(h,t) (p,q) -> (h < p && t < q)) z m,
(\(h,t) (p,q) -> (h < p && t < q)) m n,
(sort $ concat $ map (\(h,t) -> [h,t]) [x,y,z,m,n]) == [0..9]]
Prelude Data.List> result
[((0,1),(2,3),(4,5),(6,7),(8,9)),((0,1),(2,3),(4,5),(6,8),(7,9)),((0,1),(2,3),(4,6),(5,7),(8,9)),((0,1),(2,3),(4,6),(5,8),(7,9)),((0,1),(2,3),(4,7),(5,8),(6,9)),((0,1),(2,4),(3,5),(6,7),(8,9)),((0,1),(2,4),(3,5),(6,8),(7,9)),((0,1),(2,4),(3,6),(5,7),(8,9)),((0,1),(2,4),(3,6),(5,8),(7,9)),((0,1),(2,4),(3,7),(5,8),(6,9)),((0,1),(2,5),(3,6),(4,7),(8,9)),((0,1),(2,5),(3,6),(4,8),(7,9)),((0,1),(2,5),(3,7),(4,8),(6,9)),((0,1),(2,6),(3,7),(4,8),(5,9)),((0,2),(1,3),(4,5),(6,7),(8,9)),((0,2),(1,3),(4,5),(6,8),(7,9)),((0,2),(1,3),(4,6),(5,7),(8,9)),((0,2),(1,3),(4,6),(5,8),(7,9)),((0,2),(1,3),(4,7),(5,8),(6,9)),((0,2),(1,4),(3,5),(6,7),(8,9)),((0,2),(1,4),(3,5),(6,8),(7,9)),((0,2),(1,4),(3,6),(5,7),(8,9)),((0,2),(1,4),(3,6),(5,8),(7,9)),((0,2),(1,4),(3,7),(5,8),(6,9)),((0,2),(1,5),(3,6),(4,7),(8,9)),((0,2),(1,5),(3,6),(4,8),(7,9)),((0,2),(1,5),(3,7),(4,8),(6,9)),((0,2),(1,6),(3,7),(4,8),(5,9)),((0,3),(1,4),(2,5),(6,7),(8,9)),((0,3),(1,4),(2,5),(6,8),(7,9)),((0,3),(1,4),(2,6),(5,7),(8,9)),((0,3),(1,4),(2,6),(5,8),(7,9)),((0,3),(1,4),(2,7),(5,8),(6,9)),((0,3),(1,5),(2,6),(4,7),(8,9)),((0,3),(1,5),(2,6),(4,8),(7,9)),((0,3),(1,5),(2,7),(4,8),(6,9)),((0,3),(1,6),(2,7),(4,8),(5,9)),((0,4),(1,5),(2,6),(3,7),(8,9)),((0,4),(1,5),(2,6),(3,8),(7,9)),((0,4),(1,5),(2,7),(3,8),(6,9)),((0,4),(1,6),(2,7),(3,8),(5,9)),((0,5),(1,6),(2,7),(3,8),(4,9))
]
Prelude Data.List>
Prelude Data.List> length result
42
def combinations_string(a,n)
return unless a.size == n.inject(:+)
s=a.combination(n[0]).to_a
n[1..-1].each do |i|
s.length.times do
x = s.pop
(a-x).combination(i){|b| s.unshift(x+b) if x[-i..-1].join < b.join}
end
end
s.map {|t| n.map{|r| t.shift(r).join }.join('-')}
end
combinations_string([*0..9],[2,2,2,2,2])
时间是 0.139533 s,个数是 945。
puts combinations_string([*0..5],[2,2,2]).join(', ')
01-25-34, 01-24-35, 01-23-45, 02-15-34, 02-14-35, 02-13-45, 03-15-24, 03-14-25, 03-12-45, 04-15-23, 04-13-25, 04-12-35, 05-14-23, 05-13-24, 05-12-34
#5 楼 @bluexuemei 是这样啊,把条件改成 ((h,t) (p,q) -> (h * 10 + t < p * 10 + q)) x y,后我试了试确实是 945 个,你这是做科研还是做游戏啊?
ghci>length result
945
ghci>