交差点を解決する


26

タスク

交通交差点構造を取得し、車両が通過するシーケンスを出力するプログラムまたは関数を作成します。

出力は、次の形式で最も4つのラインに含まれている必要があり#. x->y\n#ドットに続くシーケンス番号の数であり.xそしてy文字です["N", "E", "S", "W"]。文字で区切る必要があります->。文字列の配列を返さない場合、各行の末尾は\n(改行文字)またはシステムに相当するものでなければなりません。

入力は次の形式を取る必要があります。

  • パート1:4つの文字。それぞれがN、E、S、W(時計回り)の順にソース道路の宛先道路を持っています 使用できる文字はNSWEまたは。スペースとは、特定の道路に車両がないことを意味します。たとえば、文字列S WEは、N台の車両が南に行きたい、スペースはE台の車両がないW、S Eは西に行きたい、西は東に行きたいという意味です。
  • パート2-緊急車両のスペースまたは1文字。
  • パート3-どの2つの道路が優先順位を持っているかを決定する2つのキャラクター(たとえばNE、北と東の両方が南と西の両方よりも優先順位が高いことを意味します)。簡単な場合は、優先度の低い道路を利用できます(その場合SW)。

解決できない状況では、などのようunsolvableにユーザーに明確な1行の文字列を返すことができますno solution。JavaScriptユーザーは組み込みundefined定数を使用できます。

これはコードゴルフであるため、バイト単位の最短回答が優先されます。

交通ルール

一部のルールは国の交通ルールに従っていない場合があります。それらのいくつかは、課題を簡単にするために単純化されています。この質問を実際の交通システムのガイドとして使用しないでください。

  1. チャレンジでは、右側のトラフィックのみを使用できます。
  2. 交差点は、1つの地点で交わる正確に4つの道路で構成されています。彼らはマークされているN(「北」のためなど)、 、S、。W Eこれらの文字の代わりに使用されるべきであるxy上記の出力例です。

交差点

  1. 各道路には、最大で1台の車両があります。各道路に車両があることは保証されません。各車両は4方向のいずれかで運転できます。左折、右折、直進、またはUターンを行います。

S車両の可能な目的地

  1. 2つの車両のパスが交差しない(衝突しない)場合、それらはまったく同じ瞬間に進むことができます。2台の車両の場合、パスは衝突しません(リストは完全ではないかもしれませんが、これは意図的なものであり、単に手がかりを与えるためです)。
    • 反対方向から来て、両方がまっすぐに行くか、少なくとも一方が右に曲がって、
    • 反対方向から来て、両方とも左に曲がって、
    • 反対方向から来て、そのうちの1つが任意の方向に回転するかUターンし、もう1つがUターンします。
    • 直交方向から来て、左の1つは右に曲がり、もう1つはUターンしません

      以下のパスを衝突させない例。3番目の図面では、NがUターンしても、NのパスはEのパスと衝突することに注意してください。

ここに画像の説明を入力してください ここに画像の説明を入力してください

ここに画像の説明を入力してください ここに画像の説明を入力してください

  1. 2つのパスが衝突する場合、他のルールを使用する必要があります。2台の車両が同じ優先道路上にある場合(以下を参照)、車両に次のような権利が与えられます:
    • それらが直交方向から来る場合、右側の道路から来ます
    • もう一方が左に曲がると右に曲がる
    • 相手がUターンすると、まっすぐに進むか右に曲がります。

      以下の両方の例では、E車両は車両Sに対する優先権を持っています。

ここに画像の説明を入力してください ここに画像の説明を入力してください

以下の例では、最初にW、次にN、次にE、最後にSになります。

ここに画像の説明を入力してください

この特定の場合、プログラムの出力は次のようになります。

1. W->S
2. N->S
3. E->S
4. S->S
  1. すべてのドライバーは方向指示器を使用し、他のすべてのドライバーが行きたい場所を知っています(簡単にするために、左折とUターンを区別できると想定しています)。

  2. 道路には優先標識が付けられていることがありますが、これは上記の規則よりも重要です。優先度の高い道路には優先標識があります(優先標識画像)。優先道路が直進しない場合は、このような追加の標識も使用されます。優先度の低い道路には、降車標識または一時停止標識があります(これらは同等です)。優先度が高いのは、まったくない道路または2つの異なる道路です。プログラムのユーザーは、優先度が高い(または低い)道路を入力できる必要があります。

  3. 優先度の高い道路から来る車両は、たとえ左側にあるとしても、優先度の低い道路から来る車両よりも優先権があります。
  4. 同じ優先順位の道路から来る2台の車両のパスが衝突した場合、上記の右側のルールがアクティブになります。

    以下の例では、道路SとWに優先標識があります。これは、NとEの車両が道を譲るべきであることを意味します。S車両は右側にあるため、W車両よりも優先されます。次に、Eよりも優先度の高い道路上にあるため、Wになります。車両Nは、右側にあるため、Eからの優先権を持っています。最後に行くとE

ここに画像の説明を入力してください

この特定の場合、プログラムの出力は次のようになります。

1. S->W
2. W->N
3. N->S
4. E->W
  1. 1台(およびそれ以上)の車両が緊急車両である可能性があります。これは、どの方向から、またはどの方向に行くかに関係なく、優先順位があります(常に最初に行きます)。プログラムでは、緊急車両である車両をユーザーが入力できるようにする必要があります。最後の例では、Nが緊急車両であると考えて、Nが最初に移動し、次にS、Wが移動し、最後のEが移動します。

Nに緊急車両があるこの特定のケースでは、プログラムの出力は次のようになります。

1. N->S
2. S->W
3. W->N
4. E->W
  1. 2台の車両がまったく同じ瞬間に進むことが許可されている場合(パスが衝突せず、他の車両に道を譲る必要がない場合)、プログラムはこれを見つけて、同じシーケンス番号を持つものとして返す必要があります

    以下の例では、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
一貫した入力形式を定義する必要があると思います。「入力は任意の構造を持つことができます」は大きな赤い旗です。入力は解決策になりますか?
カルビンの趣味

@ Calvin'sHobbies質問を更新しました
-Voitcus

1-2ケースのサンプル入出力を取得できる可能性はありますか?
チャーリーウィン

それで、質問(そして私は解決策を仮定しています)、問題の道路が右ハンドルであると仮定していますか?
テルソサウルス

これは正確にどのようにGoogleの車の仕事である
コアダンプ

回答:


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よりも優先されます)注-他の優先度の要因がこの文を変更する場合があります(緊急車両、優先道路、..)

マトリックスは、4つのサブマトリックス(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

マトリックスには、各動きに優先順位を割り当てる機能が追加されています。その機能は、緊急車両、優先道路、直交方向、方向転換のタイプ、および「右から来る」車両を考慮に入れます

優先順位で動きをソートし、マトリックス値を適用します。結果のサブマトリックスには、各移動の競合と優先度が含まれます。

  • 解決不可能なケースを分析します(相互競合)
  • そうでない場合、最も優先度の高いアイテムと、それと互換性があり、以前の互換性のない動きと互換性のないすべての動きを選択し、同時に移動できる一連の動きを作成します
  • その一連の動きを書き、残りの候補者について繰り返します
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.