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

How can I speed up using a ternary operator?

我正在尝试在 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

有什么方法可以加快我的三元运算速度,还是我做错了?

这里使用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

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

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

三元语句仅适用于存在两种可能条件的情况,通常是 true/false 条件或测试结果的结果。您有三个条件:<>==,您只想输出前两个,导致逻辑不流畅且令人困惑。

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

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

因为默认行为是按空格拆分。

您可能会发现使用 case 语句比 if/elsif/else/end 构造更清晰,并且 return 方向在方法外打印。作为一般做法,通常最好打印方法的 return 值,而不是在方法内打印,因为它使方法更加通用。

此实现使用 比较 方法 <=>(例如,Fixnum#<=>, String#<=>, Array#<=>,依此类推,具体取决于 class 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