Arrays 阵列组合学
我在Ruby 2.7中工作 我有一个数组,它的元素是三种元素之一:一个字符串或一个整数,或者偶尔还有一个包含一对元素的数组(这次只包含字符串或整数)。根据我的问题的定义,没有进一步的数组嵌套级别 示例:Arrays 阵列组合学,arrays,ruby,cartesian-product,Arrays,Ruby,Cartesian Product,我在Ruby 2.7中工作 我有一个数组,它的元素是三种元素之一:一个字符串或一个整数,或者偶尔还有一个包含一对元素的数组(这次只包含字符串或整数)。根据我的问题的定义,没有进一步的数组嵌套级别 示例: w = [1, 2, 'b', 4] x = [[2, 'r'],[2, 'g']] y = [[2, 'w']] z = ['u', 6, [2, 'r']] f(w) = [ [1, 2, 'b', 4] ] f(x) = [ [2, 2], [2, 'g'], ['r', 2], ['r
w = [1, 2, 'b', 4]
x = [[2, 'r'],[2, 'g']]
y = [[2, 'w']]
z = ['u', 6, [2, 'r']]
f(w) = [ [1, 2, 'b', 4] ]
f(x) = [ [2, 2], [2, 'g'], ['r', 2], ['r', 'g'] ]
f(y) = [ [2], ['w'] ]
f(z) = [ ['u', 6, 2], ['u', 6, 'r'] ]
问题的背景是,内部数组表示可在外部数组中使用的可选方案。我正在寻找所有可能的方法从每个内部数组(如果存在)中选择一个元素,并将该元素替换到外部数组中
示例:
w = [1, 2, 'b', 4]
x = [[2, 'r'],[2, 'g']]
y = [[2, 'w']]
z = ['u', 6, [2, 'r']]
f(w) = [ [1, 2, 'b', 4] ]
f(x) = [ [2, 2], [2, 'g'], ['r', 2], ['r', 'g'] ]
f(y) = [ [2], ['w'] ]
f(z) = [ ['u', 6, 2], ['u', 6, 'r'] ]
每个选择中元素的顺序(每个解决方案的内部数组)并不重要。输出中解决方案的顺序也不重要
我可以通过选择/拒绝、转换和使用数组产品来强制回答;但我正在寻找一种尽可能简洁优雅的方法。问题中给出的规则既不精确也不完整,因此我已尽了最大努力来推断它们是什么 代码
def doit(arr)
if arr.size == 1
e = arr.first
return e.is_a?(Array) ? (arr.map { |f| [f] }) : arr
end
(first, *rest), other = arr.partition { |e| e.is_a?(Array) }
return [arr] if first.nil?
prod = first.product(*rest)
return prod if other.empty?
prod.flat_map { |a| other.map { |e| [e, *a] } }
end
看,还有
示例
doit [1, 2, 'b', 4]
#=> [[1, 2, "b", 4]]
doit [[2, 'r'],[2, 'g']]
#=> [[2, 2], [2, "g"], ["r", 2], ["r", "g"]]
doit [:a, [2, 'r'], :b, [2, 'g']]
#=> [[:a, 2, 2], [:b, 2, 2], [:a, 2, "g"], [:b, 2, "g"],
# [:a, "r", 2], [:b, "r", 2], [:a, "r", "g"], [:b, "r", "g"]]
doit [[2, 'w']]
#=> [[[2, "w"]]]
doit ['u', 6, [2, 'r']]
#=> [["u", 2], [6, 2], ["u", "r"], [6, "r"]]
doit [:a, [2, 3], :b, :c, [4, 5], :d, [6, 7]]
#=> [[:a, 2, 4, 6], [:b, 2, 4, 6], [:c, 2, 4, 6], [:d, 2, 4, 6],
# [:a, 2, 4, 7], [:b, 2, 4, 7], [:c, 2, 4, 7], [:d, 2, 4, 7],
# [:a, 2, 5, 6], [:b, 2, 5, 6], [:c, 2, 5, 6], [:d, 2, 5, 6],
# [:a, 2, 5, 7], [:b, 2, 5, 7], [:c, 2, 5, 7], [:d, 2, 5, 7],
# [:a, 3, 4, 6], [:b, 3, 4, 6], [:c, 3, 4, 6], [:d, 3, 4, 6],
# [:a, 3, 4, 7], [:b, 3, 4, 7], [:c, 3, 4, 7], [:d, 3, 4, 7],
# [:a, 3, 5, 6], [:b, 3, 5, 6], [:c, 3, 5, 6], [:d, 3, 5, 6],
# [:a, 3, 5, 7], [:b, 3, 5, 7], [:c, 3, 5, 7], [:d, 3, 5, 7]]
请注意,doit[[2,'w']]
的返回值与问题中给出的不同
解释
步骤如下
arr = [:a, [2, 'r'], :b, [2, 'g']]
(first, *rest), other = arr.partition { |e| e.is_a?(Array) }
#=> [[[2, "r"], [2, "g"]], [:a, :b]]
Ruby应用于上述表达式以获取first
、rest
和other
的值:
first
#=> [2, "r"]
rest
#=> [[2, "g"]]
other
#=> [:a, :b]
继续,因为first.nil?#=>false
在返回[arr]中,如果first.nil?
,则不返回。下一步:
prod = first.product(*rest)
#=> [[2, 2], [2, "g"], ["r", 2], ["r", "g"]]
other.empty?#=>false
在中返回prod if other.empty?
因此我们不返回
我可以通过在代码中插入put
语句并运行它来最好地解释其余的计算
prod.flat_map do |a|
puts "a = #{a}"
other.map do |e|
puts " e = :#{e}"
puts " [e, *a] = #{[e, *a]}"
[e, *a]
end
end
#=> [[:a, 2, 2], [:b, 2, 2], [:a, 2, "g"], [:b, 2, "g"],
# [:a, "r", 2], [:b, "r", 2], [:a, "r", "g"], [:b, "r", "g"]]
将显示以下内容
a = [2, 2]
e = :a
[e, *a] = [:a, 2, 2]
e = :b
[e, *a] = [:b, 2, 2]
a = [2, "g"]
e = :a
[e, *a] = [:a, 2, "g"]
e = :b
[e, *a] = [:b, 2, "g"]
a = ["r", 2]
e = :a
[e, *a] = [:a, "r", 2]
e = :b
[e, *a] = [:b, "r", 2]
a = ["r", "g"]
e = :a
[e, *a] = [:a, "r", "g"]
e = :b
[e, *a] = [:b, "r", "g"]
请用更精确的语言重新表述你的问题。
x
和f(x)
的值与中的措辞不一致,我正在寻找所有可能的方法,从每个内部数组中选择一个元素(如果存在),并将该元素替换到外部数组中——这两个元素甚至不能远程组合。如果你可以强行给出答案,发布该代码,也许我们可以对其进行优化。强迫我们从头开始重新发明解决方案是没有建设性的。