我是ruby的新手,正在解决这个问题:
有n个编号的字母和n个编号的信封。字母x不能 放入信封x。(OP只需要x的值不在索引x-1的值)我想要的是打印出所有可能的信息 例。
Array + 1的索引--->信封的数量
Array的元素--->字母的数量
Input: n = 3.
Output: [2, 3, 1], [3, 1, 2]
Input: n = 4.
Output: [2, 1, 4, 3], [2, 3, 4, 1], [2, 4, 1, 3], [3, 1, 4, 2],
[3, 4, 1, 2], [3, 4, 2, 1], [4, 1, 2, 3], [4, 3, 1, 2],
[4, 3, 2, 1]
这是我的代码:
$nums = []
def f( already, n, times )
if n > times
$nums << already.dup
return
else
1.upto(times) do |i|
next if ((already.include? i) || n == i)
already << i
f( already, n+1, times )
already.pop
end
end
end
我正在寻找更优雅的解决方案。
答案 0 :(得分:2)
使用permutation
枚举器,拒绝索引为x-1
的值与x
匹配的所有内容:
def f(n, x)
(1..n).to_a.permutation.reject{|p| p[x-1] == x}
end
> f 3, 3
=> [[1, 3, 2], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
> f 4, 4
=> [[1, 2, 4, 3], [1, 3, 4, 2], [1, 4, 2, 3], [1, 4, 3, 2], [2, 1, 4, 3], [2, 3, 4, 1], [2, 4, 1, 3], [2, 4, 3, 1], [3, 1, 4, 2], [3, 2, 4, 1], [3, 4, 1, 2], [3, 4, 2, 1], [4, 1, 2, 3], [4, 1, 3, 2], [4, 2, 1, 3], [4, 2, 3, 1], [4, 3, 1, 2], [4, 3, 2, 1]]
<强>更新强>
再次查看您的问题,目前还不清楚您是否要使用特定的x
,或者只是逻辑应该对x
的任何值都适用。如果第二个猜测是您想要的,那么请改用:
def f(n)
(1..n).to_a.permutation.reject{|p| p.any?{|x| p[x-1] == x}}
end
> f 3
=> [[2, 3, 1], [3, 1, 2]]
> f 4
=> [[2, 1, 4, 3], [2, 3, 4, 1], [2, 4, 1, 3], [3, 1, 4, 2], [3, 4, 1, 2], [3, 4, 2, 1], [4, 1, 2, 3], [4, 3, 1, 2], [4, 3, 2, 1]]