Ruby置换代码挑战

时间:2015-08-13 18:40:59

标签: ruby permutation

我正在学习ruby并且遇到了我过去几天一直在努力解决的代码挑战。希望有人在这里提供见解。

任务

是编写一个函数,打印到标准输出(stdout)可以用来准确服务N个访问者的唯一可能配置(As,Bs,Cs)的数量。

代表我们选择投放的位置的用户数量

Bs表示我们选择投放的位置b的用户数

Cs表示我们选择投放的位置c的用户数

请注意,您的函数将收到以下参数:

一个

这是一个整数,表示来自位置a

的用户数

B'/强>

这是一个整数,表示来自位置b的用户数

C

这是一个整数,表示来自位置c

的用户数

名词

这是一个整数,表示我们的服务器可以提供服务的用户数

数据限制

a,b,c的值将在[0 .. 100]范围内

n将始终小于a,b和c

的总和

示例

a = 1

b = 1

c = 1

n = 1

可能的解决方案

[1,0,0] [0,1,0] [0,0,1]

回答

3

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

每个解决方案由3个数字组成。第一个数字必须在0到a的范围内,第二个数字在0到b的范围内,第三个数字在0到c的范围内。

每个解决方案中三个数字的总和必须等于n。

您必须找出存在多少独特解决方案。

另一个例子:

a = b = c = n = 2

解决方案:

[2, 0, 0] [1, 1, 0] [0, 2, 0] [0, 1, 1] [0, 0, 2] [1, 0, 1]

答案 1 :(得分:0)

You could do that recursively:

def combos(users, remaining_assignments)
  mx = [users.first, remaining_assignments].min
  if users.size==1
    (0..mx).to_a.map { |e| [e] }
  else
    (0..mx).each_with_object([]) { |i,a|
      combos(users[1..-1], remaining_assignments-i).each { |e| a << [i] + e } }
  end
end

users = [3,2,4]
remaining_assignments = 6

combos(users, remaining_assignments)
  #=> [[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 0, 3], [0, 0, 4],
  #    [0, 1, 0], [0, 1, 1], [0, 1, 2], [0, 1, 3], [0, 1, 4],
  #    [0, 2, 0], [0, 2, 1], [0, 2, 2], [0, 2, 3], [0, 2, 4],
  #    [1, 0, 0], [1, 0, 1], [1, 0, 2], [1, 0, 3], [1, 0, 4],
  #    [1, 1, 0], [1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 1, 4],
  #    [1, 2, 0], [1, 2, 1], [1, 2, 2], [1, 2, 3], [2, 0, 0],
  #    [2, 0, 1], [2, 0, 2], [2, 0, 3], [2, 0, 4], [2, 1, 0],
  #    [2, 1, 1], [2, 1, 2], [2, 1, 3], [2, 2, 0], [2, 2, 1],
  #    [2, 2, 2], [3, 0, 0], [3, 0, 1], [3, 0, 2], [3, 0, 3],
  #    [3, 1, 0], [3, 1, 1], [3, 1, 2], [3, 2, 0], [3, 2, 1]] 

如果在每个位置投放的用户数量总和必须相等(而不是不大于)remaining_assignments,请按以下方式修改combos

def combos(users, remaining_assignments)
  if users.size==1
    [[remaining_assignments]]
  else
    mn = [0, remaining_assignments - users[1..-1].reduce(:+)].max
    mx = [users.first, remaining_assignments].min
    (mn..mx).each_with_object([]) { |i,a|
       combos(users[1..-1], remaining_assignments-i).each { |e| a << [i] + e } }
  end
end

users = [3,2,4]
remaining_assignments = 6

combos(users, remaining_assignments)
  #=> [[0, 2, 4], [1, 1, 4], [1, 2, 3], [2, 0, 4], [2, 1, 3],
  #    [2, 2, 2], [3, 0, 3], [3, 1, 2], [3, 2, 1]] 

或者,如果remaining_assignments不小于users.size,或者效率不是问题,您可以通过生成所有组合来简化,然后抛弃数字总和的那些用户超过remaining_assignments

def combos(users, remaining_assignments)
   a = users.map { |u| (0..u).to_a }
   a.shift.product(*a).select { |b| b.reduce(:+) <= remaining_assignments }
end

如果在每个位置选择的用户总数必须等于<,请移除remaining_assignments