自动驾驶模式


10

从左上角开始的直升飞机正在降落(出于这个问题的目的,在2D空间中)朝地面。它具有自动驾驶模式和手动模式。

自动驾驶模式的行为如下:

  • 如果正下方的空间是可用的,则下降至该位置。
  • 否则,完全随机地向左或向右移动一步。(它可以以此方式移动多个步骤。)

并且它会不断重复这两个步骤,直到它落地。手动模式更加智能,即使在需要向上移动或进行一些熟练操作的情况下,也会找到通往地面的最佳路径。

您的工作是确定

  1. 自动驾驶仪将在给定情况下通过,
  2. 在特定情况下,自动驾驶仪可能会失败,
  3. 自动驾驶仪将失败,但是手动模式将通过,或者
  4. 两种模式都将失败(没有有效的接地路径)。

输入值

  • 给定场景为1d或2d非空数组,使用两个不同的字符表示自由空间和受阻空间。标点符号是可选的。
  • 可选:数组的尺寸

输出量

四个预定义字符之一,指示发生了哪种情况。

样本数据

在输入中使用0(空)和1(阻止),在输出中使用1 2 3 4(如上编号)

0 0 0 0
0 1 0 0
0 0 0 1
1 1 0 0

输出: 1

0 0 1 0
1 0 0 1
0 0 0 0
0 1 1 0
0 0 0 1

输出:(2直升机将在第四行遇到1,如果处于自动驾驶模式,它有可能陷在第5行的末尾)

0 0 0 1 0
0 1 1 0 0
0 1 0 0 0
0 0 0 1 0
1 1 1 1 0

输出:(3这需要向上移动,因此自动驾驶仪会失败)

1 0 0
0 0 0

输出: 4

0 0 0 0 1
1 1 1 0 0
1 0 0 1 0
0 1 0 0 0
0 0 1 1 1

输出: 4


@MartinBüttner完成。作为旁注,您是希望人们在沙箱中发布,还是直接发布并纠正他们的错误?第二种选择较为简单,因此,除非有一定的诱因,否则我无法想象为什么要遵循第一种选择。
ghosts_in_the_code

7
我个人更喜欢沙盒,因为它使人们有更多的时间在人们开始应对挑战之前考虑潜在的错误,漏洞或丢失的测试用例。如果有人对有缺陷的挑战发布了早期答案,那么您必须在不使现有答案无效的情况下真正解决挑战。
Martin Ender

另外-输入是否始终是字符,或者它们可以是布尔值/整数/等?然后输出-可以是整数,还是必须是字符?
并非查尔斯

Answers:


1

露比259

我对此很开心。谢谢! 挑战往往是有趣而又有趣的挑战。假设问题中的“字符”可以是整数。

我认为这里的主要改进之处是:

  1. 的创造 r
  2. 第三行可怕的三元滥用很可能会变得更加可怕,但更可怕。
->a,h,w{f=->l,s=0,y=[0]{r=w-2<s%w ?w:1,1>s%w ?w:-1,w
v=(l ?r+[-w]:a[s+w]==0?[w]:r).map{|d|a[m=s+d]==0&&!y[m]?m:p}-q=[p]
a[s]>0?q:s/w>h-2?8:v[0]?v.map{|o|f[l,y[o]=o,y]}.flatten-q :r.any?{|i|a[s+i]<1}?p: !0}
g=f[p]
[8,g[0]&&g.all?,g.any?,f[8].any?,!p].index !p}

取消高尔夫(略过时,但实际关闭):

# a is a one-dimensional array of 0s and 1s, h is height, w is width
->a,h,w{
  # f recursively walks the array and returns true/false/nil for each path.
  #    True means we can reach ground.
  #    False means we are stuck in a local minimum and cannot escape
  #    Nil means we reached a local dead-end and need to backtrack.
  # l: {true=>"manual", false=>"autopilot"}
  # s: the position index
  # y: an array of booleans - true-ish means we've visited that square before
  #         (this is to prevent infinite loops, esp in manual mode)
  f=->l,s=0,y=[0]{
    # d: all the legal deltas from s (maximally, that's [1,-1,w,-w], aka [LRDU])
    # r: but the right and left get tricky on the edges, so let's pre-calculate those
    #    we'll default to "down" if "left" or "right" are illegal
    r=[w-2<s%w ?w:1,1>s%w ?w:-1]
    # if manual, [LRDU]; if auto, and you can go down, [D]. else, [LR] 
    d=l ?r+[w,-w]:a[s+w]==0?[w]:r
    # v: the legal deltas that you can go to from s (that is, unvisited and unblocked)
    v=d.map{|d|a[m=s+d]==0&&!y[m]?m:p}-[p]


    a[s]>0 ? [p]     # if we're currently blocked, return [nil] (this is only the case when a[0]==1)
      : s/w>h-2 ? !p # if we're at the bottom, return true
        : v[0] ?     # if we have a place to go....
        v.map{|o|f[l,y[o]=o,y]}.flatten-[p] # recurse with each step.
                                            # y[o]=o is a neat trick to make y[o] truthy and return o
          : r.any?{|i|a[s+i]==0} ? # otherwise, we have nowhere to go. If we could visit left/right, but have already been there
            p                      #    this is not a dead-end - return nil to remove this path
            : !!p                  # If we have a true dead-end (auto-mode with a local minimum), false
  }
  # g is the auto flight
  g=f[p]
  # finally, choose the first "true" out of:
  # 0: always 8.  Cuz why not 8?
  # 1: there is at least one auto path, and all are truthy
  # 2: any auto path is truthy
  # 3: any manual path is truthy
  # 4: true
  [8,g[0]&&g.all?,g.any?,f[!p].any?,!p].index !p
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.