如何加快使用三元运算符?

时间:2016-06-13 17:54:33

标签: ruby optimization ternary

我试图在100毫秒的响应时间内回答有关坐标的挑战问题。我通过STDIN获得了以下值,并被告知回复指示("NE""W"等。

@light_x, @light_y, @initial_tx, @initial_ty = gets.split(" ").collect {|x| x.to_i}

我想弄清楚为什么这次尝试会超时:

print @light_y > @initial_ty ? "S" : "N" unless @light_y == @initial_ty
print @light_x > @initial_tx ? "E" : "W" unless @light_x == @initial_tx

虽然这种尝试没有:

if @light_x > @initial_tx && @light_y > @initial_ty
    puts "SE"
elsif @light_x < @initial_tx && @light_y > @initial_ty
    puts "SW"
elsif @light_x > @initial_tx && @light_y < @initial_ty
    puts "NE"
elsif @light_x < @initial_tx && @light_y < @initial_ty
    puts "NW"
elsif @light_x < @initial_tx && @light_y == @initial_ty
    puts "W"
elsif @light_x > @initial_tx && @light_y == @initial_ty
    puts "E" 
elsif @light_y > @initial_ty && @light_x == @initial_tx
    puts "S" 
elsif @light_y < @initial_ty && @light_x == @initial_tx
    puts "N"
else
end

有没有办法加速我的三元组,或者我是以错误的方式解决这个问题?

3 个答案:

答案 0 :(得分:1)

我认为主要问题不是速度,而是逻辑的清晰度。我重写了这些:

print @light_y > @initial_ty ? "S" : "N" unless @light_y == @initial_ty
print @light_x > @initial_tx ? "E" : "W" unless @light_x == @initial_tx  

为:

if @light_y > @initial_ty
  print 'S'
elsif @light_y < @initial_ty
  print 'N'
end

if @light_x > @initial_tx
  print 'E'
elsif @light_x < @initial_tx
  print 'W'
end

三元语句仅在有两种可能条件时才适用,通常是真/假条件或测试结果的结果。您有三个条件:<>==并且您只想输出前两个条件,从而导致逻辑无法流动且令人困惑

同样,我认为你可以减少这个:

if @light_x > @initial_tx && @light_y > @initial_ty
  puts "SE"
elsif @light_x < @initial_tx && @light_y > @initial_ty
  puts "SW"
elsif @light_x > @initial_tx && @light_y < @initial_ty
  puts "NE"
elsif @light_x < @initial_tx && @light_y < @initial_ty
  puts "NW"
elsif @light_x < @initial_tx && @light_y == @initial_ty
  puts "W"
elsif @light_x > @initial_tx && @light_y == @initial_ty
  puts "E" 
elsif @light_y > @initial_ty && @light_x == @initial_tx
  puts "S" 
elsif @light_y < @initial_ty && @light_x == @initial_tx
  puts "N"
else
end

为:

y_direction = if @light_y > @initial_ty
                'S'
              elsif @light_y < @initial_ty
                'N'
              else
                ''
              end

x_direction = if @light_x > @initial_tx
                'E'
              elsif @light_x < @initial_tx
                'W'
              else
                ''
              end

puts y_direction + x_direction              

这些都是未经测试的,但它看起来是正确的。

代码的更改应运行得更快,因为代码减少到更少的测试。它也更容易理解,你的未来将会欣赏它。

最后:

gets.split(" ")

可以写成:

gets.split

因为默认行为是在空格上拆分。

答案 1 :(得分:1)

您可能会发现使用case语句而不是if/elsif/else/end构造更清楚,并返回方向,以便在方法外部打印。作为一般惯例,通常最好打印方法的返回值,而不是在方法中打印,因为它使方法更通用。

此实现使用比较方法<=>(例如Fixnum#<=>String#<=>Array#<=>等,具体取决于direction的参数所属的类。

def direction(light_x, light_y, init_tx, init_ty)
  case light_x <=> init_tx
  when -1   # light_x < init_tx
    case light_y <=> init_ty
    when -1 then "NW"
    when  0 then "W"
    when  1 then "SW"
    end
  when 0    # light_x = init_tx
    case light_y <=> init_ty  
    when -1 then "N"
    when  1 then "S"
    end
  when 1    # light_x > init_tx
    case light_y <=> init_ty
    when -1 then "NE"
    when  0 then "E"
    when  1 then "SE"
    end
  end
end

puts direction(3,2,1,1)
# SE
puts direction(1,2,1,1)
# S
puts direction(1,2,3,4)
# NW

另一种选择是使用哈希。

h = { [-1,-1]=>"NW", [-1,0]=>"W", [-1,1]=>"SW",
      [ 0,-1]=>"N",  [ 0,1]=>"S",
      [ 1,-1]=>"NE", [ 1,0]=>"E", [ 1,1]=>"SE" }

light_x, light_y, init_tx, init_ty = 3, 2, 1, 1
puts h[[light_x<=>init_tx, light_y<=>init_ty]]
# SE
light_x, light_y, init_tx, init_ty = 1, 2, 1, 1
puts h[[light_x<=>init_tx, light_y<=>init_ty]]
# S
light_x, light_y, init_tx, init_ty = 1, 2, 3, 4
puts h[[light_x<=>init_tx, light_y<=>init_ty]]
# NW

答案 2 :(得分:0)

使用puts代替print

print @light_y > @initial_ty ? "S" : "N" unless @light_y == @initial_ty
print @light_x > @initial_tx ? "E" : "W" unless @light_x == @initial_tx