有一个包含两个区别元素的无序数组:
arr = ["portrait", "landscape", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "portrait", "landscape", "landscape"]
在这个例子中,调查“排序”数组,每四个landscape
有一个portraits
:
4 portraits
1 landscape
4 portraits
1 landscape
...
如果不是单线,那么实现这一目标的最短途径是什么?
答案 0 :(得分:3)
我猜是否有"肖像"没有"#34;重合"与#34;景观的数量"然后它连续添加其余的:
arr = %w[portrait landscape portrait portrait portrait portrait portrait portrait portrait portrait portrait portrait portrait portrait portrait portrait portrait portrait landscape landscape]
landscapes, portraits = arr.sort.slice_when { |a, b| a != b }.to_a
p portraits.each_slice(4).flat_map.with_index { |e, i| e << landscapes[i] }.compact
# ["portrait", "portrait", "portrait", "portrait", "landscape", "portrait", "portrait", "portrait", "portrait", "landscape", "portrait", "portrait", "portrait", "portrait", "landscape", "portrait", "portrait", "portrait", "portrait", "portrait"]
答案 1 :(得分:0)
不知道你的后备是什么意思,这里有一个如何实现你想要的例证。它可能不是最优雅的解决方案,但它很简单:
#!/usr/bin/env ruby
arr = (['P'] * 32 + ['L'] * 12).shuffle # as an example
ps, ls = arr.partition { |element| element == 'P' }
result = []
loop do
portrait_count = [4, ps.size].min
portrait_count.times { result << ps.shift }
landscape_count = [1, ls.size].min
landscape_count.times { result << ls.shift }
break if ps.empty? && ls.empty?
end
puts result.each_slice(5) { |slice| p slice }
=begin
Outputs:
["P", "P", "P", "P", "L"]
["P", "P", "P", "P", "L"]
["P", "P", "P", "P", "L"]
["P", "P", "P", "P", "L"]
["P", "P", "P", "P", "L"]
["P", "P", "P", "P", "L"]
["P", "P", "P", "P", "L"]
["P", "P", "P", "P", "L"]
["L", "L", "L", "L"]
=end
我假设每件物品不仅仅是一幅“肖像”。或者&#39; landscape&#39;切换,这就是我按顺序从数组中获取元素的原因。
答案 2 :(得分:0)
这种方法强调计算效率。我计算数组中“肖像”的数量,并从中计算四个组的数量以及剩余的“肖像”和“风景”的数量。然后我使用这三个量来构造所需的数组,这不需要任何迭代步骤。
<强>代码强>
def rearrange(arr)
nbr_portraits = arr.count("portrait")
nbr_landscapes = arr.size - nbr_portraits
groups_of_4_portraits = [nbr_portraits/4, nbr_landscapes].min
nbr_portraits -= 4 * groups_of_4_portraits
nbr_landscapes -= groups_of_4_portraits
[*[*["portrait"]*4, "landscape"]*groups_of_4_portraits,
*["portrait"] * nbr_portraits, *["landscape"] * nbr_landscapes]
end
<强>实施例强>
arr = ["portrait", "landscape", "portrait", "portrait", "portrait", "portrait",
"portrait", "portrait", "portrait", "portrait", "portrait", "portrait",
"portrait", "portrait", "portrait", "portrait", "portrait", "portrait",
"landscape", "landscape"]
rearrange arr
#=> ["portrait", "portrait", "portrait", "portrait", "landscape",
# "portrait", "portrait", "portrait", "portrait", "landscape",
# "portrait", "portrait", "portrait", "portrait", "landscape",
# "portrait", "portrait", "portrait", "portrait", "portrait"]
rearrange %w| portrait portrait portrait landscape portrait portrait
portrait portrait portrait portrait |
#=> ["portrait", "portrait", "portrait", "portrait", "landscape",
# "portrait", "portrait", "portrait", "portrait", "portrait"]
rearrange %w| portrait portrait portrait portrait portrait |
#=> ["portrait", "portrait", "portrait", "portrait", "portrait"]
rearrange %w| landscape landscape portrait landscape portrait |
#=> ["portrait", "portrait", "landscape", "landscape", "landscape"]
rearrange %w| landscape landscape landscape landscape |
#=> ["landscape", "landscape", "landscape", "landscape"]
rearrange []
#=> []
<强>解释强>
对于上述arr
,步骤如下。
nbr_portraits = arr.count("portrait")
#=> 17
nbr_landscapes = arr.size - nbr_portraits
#=> 3
groups_of_4_portraits = [nbr_portraits/4, nbr_landscapes].min
#=> 3
nbr_portraits -= 4 * groups_of_4_portraits
#=> 5
nbr_landscapes -= groups_of_4_portraits
#=> 0
b = ["portrait"] * 4
#=> ["portrait", "portrait", "portrait", "portrait"]
c = [*b, "landscape"]
#=> ["portrait", "portrait", "portrait", "portrait", "landscape"]
d = c * groups_of_4_portraits
#=> ["portrait", "portrait", "portrait", "portrait", "landscape",
# "portrait", "portrait", "portrait", "portrait", "landscape",
# "portrait", "portrait", "portrait", "portrait", "landscape"]
e = ["portrait"] * nbr_portraits
#=> ["portrait", "portrait", "portrait", "portrait", "portrait"]
f = ["landscape"] * nbr_landscapes
#=> []
[*d, *e, *f]
#=> ["portrait", "portrait", "portrait", "portrait", "landscape",
# "portrait", "portrait", "portrait", "portrait", "landscape",
# "portrait", "portrait", "portrait", "portrait", "landscape",
# "portrait", "portrait", "portrait", "portrait", "portrait"]
快速基准
这里我将上述方法与塞巴斯蒂安和基思的解决方案进行比较。结果不能直接比较,因为我们对问题的理解不同。凯斯和我把任何剩下的“肖像”或“风景”放在最后(“肖像”的第一个),而塞巴斯蒂安只留下了剩下的“肖像”,最后丢弃了任何左边 - “风景”的。
require 'fruity'
np = 100
nl = 120
p (arr = [*["portrait"]*np, *["landscape"]*nl].shuffle).size
def sebastian(arr)
landscapes, portraits = arr.sort.slice_when { |a, b| a != b }.to_a
portraits.each_slice(4).flat_map.with_index { |e, i| e << landscapes[i] }.compact
end
def keith(arr)
ps, ls = arr.partition { |element| element == 'portrait' }
result = []
loop do
portrait_count = [4, ps.size].min
portrait_count.times { result << ps.shift }
landscape_count = [1, ls.size].min
landscape_count.times { result << ls.shift }
break if ps.empty? && ls.empty?
end
result
end
compare(
Sebastian: -> { sebastian arr },
Keith: -> { keith arr },
Cary: -> { rearrange arr }
)
Running each test 64 times. Test will take about 1 second.
Cary is faster than Keith by 5x ± 1.0
Keith is similar to Sebastian