这是另一种实现@ pangpang答案的方法。我也试图解释这种方法的基本思想。
代码
def perm_sums(arr0, arr1)
sz = arr0.size
at = [arr0, arr1].transpose
(0...2**sz).map { |n| sz.times.reduce(0) { |t,i| t + at[i][n[i]] } }
end
例
arr0 = [1,2,3]
arr1 = [6,7,8]
perm_sums(arr0, arr1) #=> [6, 11, 11, 16, 11, 16, 16, 21]
说明
对于上面的示例:
sz = arr0.size #=> 3
at = [arr0, arr1].transpose #=> [[1, 6], [2, 7], [3, 8]]
这当然与arr0.zip(arr1)
相同。
e0 = (0...2**sz).map #=> #<Enumerator: 0...8:map>
我们可以通过将其转换为一个数组查看此枚举的元素:
e0.to_a #=> [0, 1, 2, 3, 4, 5, 6, 7]
的e0
第一元件被传递到块和分配给该块变量:
n = e0.next #=> 0
n=0
没有那么有趣,因为它的二进制表示都是零位。让我们来看看,而不是在n=3
:
n = e0.next #=> 1
n = e0.next #=> 2
n = e0.next #=> 3
e1 = sz.times #=> #<Enumerator: 3:times>
e1.to_a #=> [0, 1, 2]
块计算使用Fixnum#[]。的n=3
二进制表示由字符串显示:
3.to_s(2).rjust(sz,'0') #=> "011"
3[i]
给出的第i个二进制值的最显著位:
3[0] #=> 1
3[1] #=> 1
3[2] #=> 0
块计算如下进行。 reduce
设置块变量t
到的0
初始值,然后将每个e1
到该块中的三个要素:
t = 0
i = e1.next #=> 0
t + at[i][n[i]] #=> 0 + at[0][n[0]] => [1, 6][3[0]] => [1, 6][1] => 6
t = 6
i = e1.next #=> 1
t + at[i][n[i]] #=> 1 + at[1][3[1]] => 1 + [2,7][1] => 8
t = 8
i = e1.next #=> 2
t + at[i][n[i]] #=> 8 + at[2][n[2]] => 8 + [3,8][3[2]] => 8 + [3,8][0] => 11
i = e1.next
#=> StopIteration: iteration reached an end
所以数量3
被映射到11
。其他计算也是相似的。
请注意,如果我们将at[i][n[i]]
替换为at[i][n[sz-1-i]]
(即将位从高位提取到低位),我们将得到相同的答案。
我知道有更好的办法! –
从我的理解,结果也是为了点数吧?从000开始,以111结尾 – Crone
是的。每个等级依次递增。 – mudasobwa