Редактировать: С v3.0 У меня наконец-то есть что-то уважительное. Как обычно, ключ искал проблему правильно. Мне пришло в голову, что я могу многократно переставлять normal_values << special
, power - 1
раз, то для каждой из этих перестановок будет добавлен еще один элемент. Если перестановка содержала по крайней мере один special
, можно было бы добавить любой элемент normal_values << special
; в противном случае необходимо добавить special
.
def limited_cartesian(values, special, power)
all_vals = values + [special]
all_vals.repeated_permutation(power-1).map do |p|
if p.include?(special)
*all_vals.each_with_object([]) { |v,a| a << (p + [v]) }
else
p + [special]
end
end
end
limited_cartesian(values, 'z', 1)
# [["z"]]
limited_cartesian(values, 'z', 2)
# => [["a", "z"], ["b", "z"], ["c", "z"],
# ["z", "a"], ["z", "b"], ["z", "c"],
# ["z", "z"]]
limited_cartesian(values, 'z', 3)
# => [["a", "a", "z"], ["a", "b", "z"], ["a", "c", "z"],
# ["a", "z", "a"], ["a", "z", "b"], ["a", "z", "c"],
# ["a", "z", "z"], ["b", "a", "z"], ["b", "b", "z"],
# ["b", "c", "z"], ["b", "z", "a"], ["b", "z", "b"],
# ["b", "z", "c"], ["b", "z", "z"], ["c", "a", "z"],
# ["c", "b", "z"], ["c", "c", "z"], ["c", "z", "a"],
# ["c", "z", "b"], ["c", "z", "c"], ["c", "z", "z"],
# ["z", "a", "a"], ["z", "a", "b"], ["z", "a", "c"],
# ["z", "a", "z"], ["z", "b", "a"], ["z", "b", "b"],
# ["z", "b", "c"], ["z", "b", "z"], ["z", "c", "a"],
# ["z", "c", "b"], ["z", "c", "c"], ["z", "c", "z"],
# ["z", "z", "a"], ["z", "z", "b"], ["z", "z", "c"],
# ["z", "z", "z"]]
Это мой v2.1, который работает, но не очень. Я оставлю это для записи.
def limited_cartesian(values, special, power)
ndx = Array(0...power)
ndx[1..-1].each_with_object([[special]*power]) do |i,a|
ndx.combination(i).to_a.product(values.repeated_permutation(power-i).to_a)
.each { |pos, val| a << stuff_special(special, pos, val.dup) }
end
end
def stuff_special(special, pos, vals)
pos.each_with_object(Array.new(pos.size + vals.size)) {|j,r|
r[j] = special }.map {|e| e.nil? ? vals.shift : e }
end
# e.g., stuff_special('z', [1,4], ["a","b","c"]) => ["a","z","b","c","z"]
Действительно ли '' z'' находится в 'normal_values'? –
@mu Это может быть, если вы этого хотите; Я вытащил его, потому что он обрабатывается специально, и в моем фактическом коде это то, что я впрыскиваю в массив не нормальных значений. – Phrogz
'limited_cartesian (normal_values," z ", 3) .size => 37' !! Вероятно, вам известно (из ответа на связанный с вами вопрос, который вы задали недавно), что первые две строки «limited_cartesian» выше могут быть заменены на «toomany = [special, * values] .repeated_permutation (power)». –