2016-09-28 11 views
7

我有一个问题,我试图创建一个方向阵列,其中每个方向都不是多余的。如何从数组中删除相反的值?

plan = ["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"] 

正如你可以看到最这项计划的价值是多余的,你不妨直接告诉人去"WEST"

plan = ["NORTH", "WEST", "SOUTH", "EAST"] 

我也希望上面的计划返回一个空数组。

+0

你有没有去?我们可以通过您现有的策略来帮助您? –

+1

@kallax,这不会工作,他没有删除多余的值,他正在删除值对,如南北 – davidhu2000

+0

我很确定我必须在这里使用delete_if,但我无法弄清楚如何使用它。我对ruby仍然陌生。 –

回答

5

鉴于方向的数组:

plan = %w[NORTH SOUTH SOUTH EAST WEST NORTH WEST] 
#=> ["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"] 

我的方向转化成xy坐标:

x, y = 0, 0 

plan.each do |direction| 
    case direction 
    when 'NORTH' then y += 1 
    when 'EAST' then x += 1 
    when 'SOUTH' then y -= 1 
    when 'WEST' then x -= 1 
    end 
end 

'NORTH'增量y'SOUTH'递减y,与'EAST'/'WEST'x相同。

随着例如数组这给:

x #=> -1 
y #=> 0 

这些都必须翻译回方向的数组:

[ 
    *Array.new(y.abs) { y.positive? ? 'NORTH' : 'SOUTH' }, 
    *Array.new(x.abs) { x.positive? ? 'EAST' : 'WEST' } 
] 
#=> ["WEST"] 

虽然这不是最短的代码,这是比较容易掌握IMO。

+0

令人敬畏的做法! –

+0

我的意思是 - 喜欢这个解决方案,仅仅通过阅读就可以很容易地理解,甚至不用停下来思考它 - 我希望我能够更多地赞扬它。 –

+0

现在我明白了!你的代码很漂亮,先生。 –

4
OPPOSITES = { 
    'NORTH' => 'SOUTH', 
    'WEST' => 'EAST', 
    'EAST' => 'WEST', 
    'SOUTH' => 'NORTH', 
} 

frequencies = plan.group_by(&:itself).map do |direction, occurrences| 
    [direction, occurrences.size] 
end.to_h 

OPPOSITES.flat_map do |direction, opposite_direction| 
    uncounteracted_occurances = 
    frequencies[direction] - frequencies[opposite_direction] 

    [direction] * [uncounteracted_occurances, 0].max 
end 
+0

我觉得这个解决方案已经超出了我的头。谢谢! –

+0

@JackKelly我可以解释一下,只是指出让你感到困惑的部分。您也可以在REPL中一步一步地尝试它。 – ndn

2
def simplify(plan) 
    h = { "SOUTH"=>"NORTH", "NORTH"=>"SOUTH", "EAST"=>"WEST", "WEST"=>"EAST" } 
    plan.each_with_object([]) { |direction, arr| 
    (idx = arr.index(h[direction])) ? arr.delete_at(idx) : arr << direction } 
end 

simplify ["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"] 
    #=> ["WEST"] 
simplify ["NORTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST", "WEST"] 
    #=> ["NORTH", "WEST", "WEST"] 
simplify ["NORTH", "EAST", "WEST", "NORTH", "WEST"] 
    #=> ["NORTH", "NORTH", "WEST"] 
+0

我最初有一个冗长的常规答案,然后阅读@斯蒂芬的可爱答案,这给了我这个想法。 –

0

这是一种应该直接遵循的方法。与我删除的近似答案一样,它正在考虑数字2D平面上的方向,但没有不必要的复杂性(双关意图)。因此,这与@Stefan发布的优秀答案在概念上相似。

def kanye plan 
    r = plan.count("EAST") - plan.count("WEST") 
    i = plan.count("NORTH") - plan.count("SOUTH") 

    res = [] 
    r.positive? ? r.times { res << "EAST" } : (-r).times { res << "WEST" } 
    i.positive? ? i.times { res << "NORTH" } : (-i).times { res << "SOUTH" } 
    res 
end 

例子:

plan = ["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"] 
kanye plan #=> ["WEST"] 

plan = ["NORTH", "WEST", "SOUTH", "EAST"] 
kanye plan #=> [] 

plan = ["NORTH"] 
kanye plan #=> ["NORTH"] 

plan = [] 
kanye plan #=> [] 
0

我们可以用阿根高斯平面来表示的地理坐标,其中实部,我们会告诉南北运动而虚部的东西方向。通过这种方式,运行简单的复数和就足够了。

plan=["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"] 
dict = {"NORTH"=>1, "SOUTH"=>-1, "EAST"=>(0+1i), "WEST"=>(0-1i)} 

# We substitute for each direction a complex number 
dict.each{|coord,number| plan.map!{|item| item==coord ? number : item}} 
# We run a simple sum 
direction = plan.reduce(&:+) # (0-1i) 
puts dict.key(direction) #=> WEST 

re=direction.real 
im=direction.imag 

if re!=0 and im!=0 
    puts "Direction: #{re.abs} #{dict.key(re/re.abs)} #{im.abs} #{dict.key((im/im.abs) *(1i))}" 
elsif re!=0 and im==0 
    puts "Direction: #{re.abs} #{dict.key(re/re.abs)}" 
elsif re==0 and im!=0 
    puts "Direction: #{im.abs} #{dict.key((im/im.abs) *(1i))}" 
else 
    puts "I did not move" 
end 

#=> Direction: 1 WEST