解决交通路口


26

任务

编写采用交通交叉路口结构并输出车辆通过顺序的程序或函数。

输出应包含至多4行的格式如下#. x->y\n,其中#是一个序列号数,然后由点.xy是字符["N", "E", "S", "W"]。它们应以字符分隔->。如果不返回字符串数组,则每行必须以\n(换行符)或与您的系统等效的结尾。

输入应采用以下形式:

  • 第1部分:四个字符,每个字符的源道路的目标道路的顺序为N,E,S,W(顺时针)。允许的字符是NSWE。空间意味着在特定道路上没有车辆。例如,字符串S WE表示N辆车希望向南行驶,空格表示没有E车,W意味着S 车向西行驶,E意味着West车向东行驶。
  • 第2部分-表示紧急车辆的空格或单个字母。
  • 第三部分-两个字符确定哪两条道路具有优先权(例如,NE意味着北部和东部的优先级均高于南部和西部)。如果更方便,您可以选择优先等级较低的道路(在这种情况下SW)。

在无法解决的情况下,你被允许返回一个行字符串是明确告知用户,如unsolvableno solution和类似的。JavaScript用户可以采用内置undefined常量。

这是一个代码高尔夫球,因此最短的答案以字节为单位。

交通规则

请注意,某些规则可能不符合您所在国家/地区的交通规则。其中一些已简化以使挑战更容易。不要将此问题用作现实交通系统的指南。

  1. 对于挑战,您只能使用右侧流量。
  2. 交通交叉路口恰好由四条相交的道路组成。它们被标记N(为“北”) ,S,。W 在上面的输出示例中,E应使用这些字母代替xy

一个十字路口

  1. 每条道路上最多只能有一辆车。不能保证每条道路上都有车辆。每辆车可以在四个方向中的任何一个方向上行驶。左转,右转,直行或进行掉头

S车辆的可能目的地

  1. 如果两辆车的路径不相交(它们不碰撞),它们可以在同一时刻行驶。如果有两辆车,路径不会发生冲突(列表可能不完整,但这是有意的,仅为您提供一个线索):
    • 来自相反的方向,并且都直走,或者至少其中一个向右转,
    • 来自相反的方向,都向左转,
    • 来自相反的方向,其中一个可以向任何方向旋转或掉头,而另一个可以掉头,
    • 来自正交方向,左一个向右转,另一个不掉头

      下面是一些不冲突路径的示例。请注意,在第三个图形上,即使N掉头,N的任何路径也会与E的路径相撞。

在此处输入图片说明 在此处输入图片说明

在此处输入图片说明 在此处输入图片说明

  1. 如果两条路径冲突,则必须使用其他规则。如果有两辆车在同一优先道路上(见下文),则该车的通行权为
    • 如果来自正交方向,则来自右侧的道路
    • 如果另一个向左转,则向右转
    • 直行或向右转(如果对方掉头)。

      在下面的两个示例中,E车都拥有高于S的通行权。

在此处输入图片说明 在此处输入图片说明

在下面的示例中,首先是W,然后是N,然后是E,最后是S。

在此处输入图片说明

对于这种特殊情况,程序的输出应为:

1. W->S
2. N->S
3. E->S
4. S->S
  1. 所有驾驶员都使用转向信号灯,并且知道其他所有人都想去哪里(为简单起见,我们假定可以区分左转弯和掉头)。

  2. 有时,道路会被赋予优先权标志,这比上述规则更为重要。具有较高优先级的道路具有优先标志(优先标志图像)。如果优先道路不能直走,那么还会使用其他标志,例如这样。优先级较低的道路具有屈服标志停车标志(它们是等效的)。没有一条或恰好两条不同的道路具有更高的优先级。程序的用户应该能够输入优先级较高(或较低)的道路。

  3. 来自优先级较高的道路的车辆比来自优先级较低的道路的车辆具有路权,即使该车辆位于左侧。
  4. 如果来自同一优先级的道路上的两辆车的路径发生冲突,则上面的右侧规则将处于活动状态。

    在下面的示例中,S和W道路具有优先权标志,这意味着N和E上的车辆应为它们提供道路。S车辆的优先级高于W车辆,因为它在右侧,因此先行。然后转到W,因为它在比E高的道路上。车辆N拥有从E离开的权利,因为它在其右侧。到最后E。

在此处输入图片说明

对于这种特殊情况,程序的输出应为:

1. S->W
2. W->N
3. N->S
4. E->W
  1. 可能有一个(也没有其他)车辆是紧急车辆,无论它来自哪个方向或去向以及它具有什么标志(始终优先),它都具有优先级。该程序应允许用户进入,哪辆车是紧急车。考虑到在最后一个示例中N是紧急车辆,N首先行驶,然后是S,W,最后是E。

对于这种特殊情况,当紧急车辆位于N时,程序的输出应为:

1. N->S
2. S->W
3. W->N
4. E->W
  1. 如果允许两辆车在同一时刻行驶(它们的路径不相撞,并且不必让路给其他车辆),则程序应找出并返回相同的序号

    在以下示例中,N和E以及E和S或W和E的路径不冲突。因为S必须让位给N,而W必须让位给S,所以S不能与E等同时进行。N和E可以。因此,首先N和E在一起,然后是S,最后是W。

在此处输入图片说明

程序的正确输出应为:

1. N->W
1. E->E
2. S->W
3. W->N

您可以自由选择线的顺序1N->W / E->E相当于E->E / N->W

  1. 有时,交通可能导致无法解决的情况,这不允许任何车辆行驶。在现实生活中,其中一名驾驶员自愿辞职便可以解决。在这里,您的程序应输出unsolvable等,如问题的第一部分所述。

    以下是无法解决的情况的示例。E应该让位给W,W应该让位给S,S应该让位给E。

在此处输入图片说明


3
我认为应该定义一致的输入格式。“输入可以具有您喜欢的任何结构”是一个很大的危险信号。输入可以解决吗?
加尔文的爱好2015年

@ Calvin'sHobbies我已经更新了问题
Voitcus

我们有机会获得1-2种情况的示例输入/输出吗?
查理·永利

因此,问题(我假设是解决方案)假设所讨论的道路是右旋行驶?
Tersosauros's

这正是Google Cars的工作方式
coredump

Answers:


8

Q,645字节

r:{(1_x),*x}                                                    /rot
R:{x 3,!3}                                                      /-rot
A:4 4#/:@[16#0;;:;]'[(&0100011001111100b;&0001111101100010b;&0010001111000100b;0);(&0 6 2;&0 1 7;&0 3 3;0)]
K:,/{,'/A x}'3 R\3 0 2 1                                        /Konflick matrix
G:3 R\|E:"NESW"                                                 /E:NESW  G:WSEN NWSE ENWS SENW    
m:{x-y*_x%y}                                                    /mod
t:{1=+/m'[_x%4;2]}                                              /orthogonal
w:{-1($x),". ",y[0],"->",y 1;}                               /write
b:{_x%4}                                                        /n-> base dir.
g:m[;4]                                                         /n-> turn
e:(!4)in                                                        /exists
d:{s:r a:e b x;R s&~a}                                       /right free
I:{(G[a]?x 1)+4*a:E?*x}                                         /"dd"->n
O:{E[a],G[a:b x]g x}                                            /n-> "dd"
P:{N::(y=4)&z~4 4;a@&0<a:(@[4#0;b x;:;4-g x])+(5*d x)+(24*e z)+99*e y}          /priority
H:{a::K ./:/:x,/:\:x; if[N&2 in *a;:,0N]; x@&{~|/x[;z]'y}[a]'[!:'u+1;u:!#x]}    /each set of concurrent movements
f:{i:I'(E,'a)@&~^a:4#x; i:i@p:>P[i;E?x 4;E?x 5 6]; {0<#x 1}{a:H x 1;$[a~,0N;-1"unsolvable";w[*x]'O'a];$[a~,0N;(0;());(1+*x;x[1]@&~x[1] in a)]}/(1;i);}

评论

绝对,它不是简短(也不简单)的代码。可以(严重)压缩它,但是它留给读者练习(我花了太多时间解决这个问题)。

我已经包含了多行注释解决方案,但假设换行符为1字节,并丢弃注释(从/到行尾)以计算大小

主要困难是要完全理解所有规则。早期优化代码长度与开发复杂问题的解决方案不兼容。自下而上或自上而下的方法都无法很好地应对不可读的代码。

最后,我开发了一个决策表(冲突矩阵),该决策表具有16行16列(每个方向与每个可能的转弯组合)。项目的值为0(兼容性),1(行首选项)或2(列首选项)。它不能满足所有测试的要求,因为我不确定所有可能的情况是否都已涵盖

源文件必须具有k扩展名。启动交互式解释器(免费用于非商业用途,kx.com)并在提示时进行评估(如“测试”段落所示)

测试

q)f " WN    "
1. E->W
2. S->N

q)f " SW    "
1. E->S
2. S->W

q)f "SSSS   "
1. W->S
2. N->S
3. E->S
4. S->S

q)f "SWWN WS"
1. S->W
2. W->N
3. N->S
4. E->W

q)f "SWWNNWS"
1. N->S
2. S->W
3. W->N
4. E->W

q)f "WEWN   "
1. N->W
1. E->E
2. S->W
3. W->N

q)f " SWE   "
unsolvable

说明

基本结构是“优先级矩阵”

   N       E       S       W   
   W S E N N W S E E N W S S E N W
NW 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1
 S 0 0 0 0 0 1 1 0 0 0 1 1 2 2 2 2
 E 0 0 0 0 0 1 1 1 2 2 0 0 0 2 2 0
 N 0 0 0 0 2 2 0 0 0 2 0 0 0 0 2 0
EN 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0
 W 2 2 2 2 0 0 0 0 0 1 1 0 0 0 1 1
 S 0 2 2 0 0 0 0 0 0 1 1 1 2 2 0 0
 E 0 0 2 0 0 0 0 0 2 2 0 0 0 2 0 0
SE 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0
 N 0 0 1 1 2 2 2 2 0 0 0 0 0 1 1 0
 W 2 2 0 0 0 2 2 0 0 0 0 0 0 1 1 1
 S 0 2 0 0 0 0 2 0 0 0 0 0 2 2 0 0
WS 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0
 E 0 1 1 0 0 0 1 1 2 2 2 2 0 0 0 0
 N 0 1 1 1 2 2 0 0 0 2 2 0 0 0 0 0
 W 2 2 0 0 0 2 0 0 0 0 2 0 0 0 0 0

含义(例如)

  • m[NW][SE] 具有0值(两个动作都兼容-concurrent-)
  • m[EW][SN] 具有1值(EW比SN优先)注-其他优先级因素可能会更改此语句(紧急车辆,优先道路等)。
  • m[NE][SE] 具有2个值(SE优先于NE)注-其他优先级因素可能会更改此语句(紧急车辆,优先道路,..)

可以使用四种子矩阵(4x4)类型构造矩阵

  NESW  A    B    C    D
N DACB  0100 0001 0010 0000
E BDAC  0110 2222 0011 0000
S CBDA  0111 0220 2200 0000
W ACBD  2200 0020 0200 0000

矩阵补充有为每个动作分配优先级的功能。该功能考虑了紧急车辆,优先道路,正交方向,转弯类型和“从右边驶来”的车辆

我们按优先级对移动进行排序并应用矩阵值。产生的子矩阵包括每个动作的冲突和优先级。

  • 我们分析无法解决的案例(相互冲突)
  • 如果不是,我们选择最优先的项目,并且所有与之兼容且与先前不兼容的动作不兼容的机芯,并创建一组允许同时进行的机芯
  • 写下那组动作,然后遍历其他候选人
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.