我正在学习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
感谢您的帮助!
答案 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
。