我希望得到一个嵌套数组,其中包含至少包含三个元素但最多包含四个元素的单个数组。当我到达10时,我遇到了一个问题:
example = [1,2,3,4,5,6,7,8,9,10]
example.each_slice(3).to_a = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
example.each_slice(4).to_a = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]
期望的结果是:
[[1, 2, 3], [4, 5, 6], [7, 8, 9, 10]] (all arrays have 3 elements but no more than 4)
each_slice不是这样做的吗?
由于
答案 0 :(得分:2)
each_slice生成最大所需大小的切片;它不会直接完成你想要的东西,这是一种“平衡”的清单。幸运的是,我们可以到达那里。
list = (1..10).to_a
slice_count = (list.length / 3.0).floor
list.each_slice(slice_count).to_a.each {|l| l.fill nil, slice_count, 0 }.transpose.map(&:compact)
# => [[1, 4, 7, 10], [2, 5, 8], [3, 6, 9]]
这不保留排序,但它确实平衡了值。它的工作方式是它基本上创建一个值的矩阵,其中至少填充每列的前3行,第四列用于捕获溢出。
1 2 3
4 5 6
7 8 9
10 - -
然后使用#transpose从列中创建数组,然后我们压缩以删除nils。
保留订单有点困难,并且需要一些if条件。在这种情况下,具有3/4元素的数组的所需分布将影响答案。
答案 1 :(得分:1)
这是你可以做到的一种方法,它保留了顺序,并最大化了包含三个元素的数组的数量,最后放置了零个,一个或两个四个数组。
<强>代码强>
def divide_up(arr)
sz = arr.size
return nil if [0,1,2,5].include?(sz)
n3, d = sz.divmod(3)
return arr.each_slice(3).to_a if d.zero?
return arr.each_slice(4).to_a if d==n3
n3 -= d
arr[0,3*n3].each_slice(3).to_a + arr[3*n3..-1].each_slice(4).to_a
end
注意方法第五行中的d==n3
是(d==1 && n3==1) || (d==2 && n3==2)
的简写。
<强>实施例强>
16.times do |n|
arr = [*1..n]
puts "for: #{arr}:"
a=divide_up(arr)
puts " #{(a ? a : "No solution")}"
end
#=> for: []:
# No solution
# for: [1]:
# No solution
# for: [1, 2]:
# No solution
# for: [1, 2, 3]:
# [[1, 2, 3]]
# for: [1, 2, 3, 4]:
# [[1, 2, 3, 4]]
# for: [1, 2, 3, 4, 5]:
# No solution
# for: [1, 2, 3, 4, 5, 6]:
# [[1, 2, 3], [4, 5, 6]]
# for: [1, 2, 3, 4, 5, 6, 7]:
# [[1, 2, 3], [4, 5, 6, 7]]
# for: [1, 2, 3, 4, 5, 6, 7, 8]:
# [[1, 2, 3, 4], [5, 6, 7, 8]]
# for: [1, 2, 3, 4, 5, 6, 7, 8, 9]:
# [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# for: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
# [[1, 2, 3], [4, 5, 6], [7, 8, 9, 10]]
# for: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]:
# [[1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
# for: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]:
# [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
# for: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]:
# [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12, 13]]
# for: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]:
# [[1, 2, 3], [4, 5, 6], [7, 8, 9, 10], [11, 12, 13, 14]]
# for: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]:
# [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]]