我目前有一个非常大的排列数组,目前正在使用大量的RAM。这是我当前的代码,应该:
计算除了存在多个“1”或连续存在三个“2”的所有事件。
arr = [*1..3].repeated_permutation(30).to_a;
count = 0
arr.each do |x|
if not x.join('').include? '222' and x.count(1) < 2
count += 1
end
end
print count
所以基本上这会产生一个24,360个元素数组,每个数组都有30个元素。
我试图通过终端运行它,但它实际上通过14GB的RAM吃了,并且没有移动15分钟,所以我不确定这个过程在尝试访问更多RAM时是否冻结或者是否还在计算。
我的问题是:有更快的方法吗?
谢谢!
答案 0 :(得分:1)
我不确定你试图解决什么问题。如果您的代码只是一个更复杂问题的示例,并且您确实需要以编程方式检查每一个permumation,那么您可能希望尝试lazy
:
[*1..3].repeated_permutation(30).lazy.each do ||
# your condition
end
或者你可能想要使嵌套的iteratior非常明确:
[1,2,3].each do |x1|
[1,2,3].each do |x2|
[1,2,3].each do |x3|
# ...
[1,2,3].each do |x30|
permutation = [x1,x2,x3, ... , x30]
# your condition
end
end
end
end
end
但是我觉得用Ruby enumerables解决这类问题感觉不对。我们来看看你的字符串:
111111111111111111111111111111
111111111111111111111111111112
111111111111111111111111111113
111111111111111111111111111121
111111111111111111111111111122
111111111111111111111111111123
111111111111111111111111111131
...
333333333333333333333333333323
333333333333333333333333333331
333333333333333333333333333332
333333333333333333333333333333
我建议只使用enumerative combinatorics。只需查看模式并分析(或计算)您的情况true
的频率。例如,你的字符串中有28个索引可以放置222
子字符串,2222
子字符串只有27个...如果你放置一个子字符串,那么它有多可能没有{{ 1}}在字符串的其他部分?
我认为你的问题是数学问题,而不是编程问题。
答案 1 :(得分:0)
NB 这是一个不完整的答案,但我认为这个想法可能会推动正确的解决方案。
我可以想到以下方法:让我们将每个排列表示为三元数基数中的值,用零填充:
1 = 000..00001
2 = 000..00002
3 = 000..00010
4 = 000..00011
5 = 000..00012
...
现在考虑我们重申最初的任务,将零视为一个,一个视为三个,两个视为三个。到目前为止一切都很好。
整个排列列表将表示为:
(1..3**30-1).map { |e| x = e.to_s(3).rjust(30, '0') }
现在我们要应用你的条件:
def do_calc permutation_count
(1..3**permutation_count-1).inject do |memo, e|
x = e.to_s(3).rjust(permutation_count, '0')
!x.include?('111') && x.count('0') < 2 ? memo + 1 : memo
end
不幸的是,即使是permutation_count == 20
,计算也需要5分钟以上,因此可能还需要一些额外的步骤。我会考虑进一步优化。目前我希望这会给你一个提示,让你自己找到好的方法。