如何使用两个数组创建所有可能的组合

时间:2014-01-02 18:59:22

标签: ruby

我现在的问题是找到形式为a * b a,b< 100,它的数字之和是最大的,为此我决定使用数组!我制作两个数组a,b就像这样:

a = []
b = []
(1..100).map {|n| a << n}
(1..100).map {|n| b << n}

我还决定制作一个sum_of_digits方法:

class Integer
  def sum_of_digits
  self.to_s.split("").map {|p| p.to_i}.reduce(:+)
  end
end

所以现在我需要构建一个包含** b的所有组合的数组 我怎么能这样做? 谢谢!

4 个答案:

答案 0 :(得分:8)

您可以使用Array#product方法:

a = [1,2,3]
b = [4,5,6]

a.product(b)
# => [[1, 4], [1, 5], [1, 6], [2, 4], ...]

a.product(b).map { |x, y| x ** y }
# => [1, 1, 1, 16, 32, 64, 81, 243, 729]

然后,根据您的Integer#sum_of_digits定义:

a.product(b).map { |x, y| x ** y }.max_by(&:sum_of_digits)
# => 729

更新:计算数字的最大数字总和(a ** b),其中a,b是小于或等于100的自然数,我这样做:

Array(1..100)
  .repeated_permutation(2)
  .map { |a, b| (a ** b).sum_of_digits }
  .max

答案 1 :(得分:2)

跳过数组并使用范围内的repeated_permutation帮助程序获取枚举数:

(1..100).to_a.repeated_permutation(2)

在枚举器上调用to_a将获得所有排列的数组。但是,您可以直接对枚举器进行操作以提高工作效率:

(1..100).to_a.repeated_permutation(2).reduce([0]) do |m,(a,b)| 
  r = (a**b).sum_of_digits
  r > m.last ? [[a,b],r] : m
end
=> [[99, 95], 972]

虽然您可以致电map,然后找到max。这将需要立即实际保持所有排列结果。在调查员上调用reduce只需要在任何给定时间保留单个排列和先前排列的结果。

答案 2 :(得分:1)

编辑:@PinnyM正确地指出我应该使用Array#repeated_permutation而不是Array#permutation,因为后者不包括对[i,i]。为了多样化,我不是做出更正,而是将其a.permutation(2).to_a替换为a.permutation(2).to_a + a.zip(a)

  a = (1..100).to_a
  (a.permutation(2).to_a + a.zip(a)).map {|i,j| (i ** j).sum_of_digits}.max
    # => 972

获胜者是:

  (a.permutation(2).to_a + a.zip(a)).map \
    {|i,j| [i, j, (i ** j).sum_of_digits]}.max_by(&:last)
    # => [99, 95, 972] (99**95).sum_of_digits # => 972

如果i <= 3而不是i <= 100,则执行以下步骤:

a = (1..3).to_a # => [1,2,3]
b = a.permutation(2) # => #<Enumerator: [1, 2, 3]:permutation(2)>
c = b.to_a # => [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]] 
d = a.zip(a) # => [[1, 1], [2, 2], [3, 3]]
e = c + d # => [[1,2], [1,3], [2,1], [2,3], [3,1], [3,2], [1,1], [2,2], [3,3]] 
f = e.map {|i,j| (i ** j).sum_of_digits} # => [1, 1, 2, 8, 3, 9, 1, 4, 9]
f.max # => 9

在Ruby 2.0中,您可以通过将sum_of_digits替换为class Integer来限制方法refine Integer do对当前上下文(例如,类)的使用。如果您认为您可能希望在其他地方使用该方法,则可以将其放在模块中,并在需要的地方include放置模块。

答案 3 :(得分:0)

combinations = []
a.each do |n1|
  b.each { |n2| combinations << n1**n2 }
end

编辑:
你将所有的价值加倍。这就是你要找的东西吗?