4ウェイストップをスケジュールする


14

4方向の一時停止の標識に、たくさんの車が並んで待っています。誰が次に行くのか、誰がどの方向に行くのかなどについて混乱しています。明らかに最適ではありません。

あなたの仕事は、最適な方法で一時停止標識の交通をスケジュールすることです。

4つの主要な方向のそれぞれに1つずつ、ターンリクエストの4つの文字列を入力として受け取ります。各リクエストはL、左、Sストレート、またはR右のいずれかです。

LLSLRLS
SSSRRSRLLR
LLRLSR
RRRLLLL

最初の行は、交差点の北口のラインナップです。列に並んでいる最初の車が左に曲がります(つまり、東を出ます)。後続の行は、入ってくる東、南、および西の入り口用です。それで、西から来る最初の車は南を出ることを望みます。

トラフィックは一連のステップで移動します。各ステップで、行の先頭にある車のサブセットを選択して続行する必要があります。選択した車は互いに干渉してはなりません。2台の車が同じ方向から出る場合、または互いの進路を横断する必要がある場合(標準的な右ハンドル規則が与えられている場合)は干渉します。したがって、両方ともまっすぐに行きたい2つの反対の車は同じステップで行くかもしれません。4台すべてが右折を希望する場合があります。反対側の2台の車は両方同時に左折できます。

あなたの仕事は、最小限の一連のステップで交差点をスケジュールすることです。各ステップについて、入ってくる車のコンパスの方向がリストされた行を出力します。上記の例では、最小スケジュールは14ステップです。1つの最小スケジュールは次のとおりです。

N    [L from North]
E    [S from East]
E    [S from East]
E    [S from East]
NESW [L from North, R from East, L from South, R from West]
NE   [S from North]
EW   [R from East]
NESW [L from North, R from East, L from South, R from West]
W    [L from West]
EW   [L from East, L from West]
NESW [R from North, L from East, R from South, L from West]
NES  [L from North, R from East, L from West]
NS   [S from North, S from South]
SW   [R from South, L from West]

プログラムは、各ラインで50台の車を1分以内で処理できる必要があります。4つの文字列の入力とスケジュールの出力は、言語にとって便利な方法で行うことができます。

最短のプログラムが勝ちます。

より大きな例:

RRLLSSRLSLLSSLRSLR
RLSLRLSLSSRLRLRRLLSSRLR
RLSLRLRRLSSLSLLRLSSL
LLLRRRSSRSLRSSSSLLRRRR

最低38ラウンドが必要です。1つの可能な解決策:

E
EW
E
ESW
S
NS
ES
NESW
NSW
ESW
ES
NSW
NS
NS
NW
EW
NSW
NS
EW
NES
EW
NSW
NE
E
NE
EW
E
E
EW
EW
EW
W
ESW
NSW
NSW
NS
NSW
NEW


最初の例の最小スケジュールをどのように計算しましたか?これは有効な13段階のスケジュールだと思います:NSW、NSW、ESW、EW、EW、NES、NE、EW、NE、NEW、NS、ES、E
ESultanik

@ESultanik:4番目のステップであるEWでは、東がまっすぐ進み、西が左に曲がっています。それは許可された構成ではありません。
キースランドール

@Fatalize:動的プログラミングを使用してそれを行うプログラムがあります。
キースランドール

ああ、それについてすみません。プログラムにバグがありました。すぐに回答を投稿します…
ESultanik

回答:


3

Python、1219バイト

私はこれをゴルフしようとしてあまり時間/労力を費やしませんでしたが、他の答えが現れ始めたら改善するかもしれません。許容できるヒューリスティックA *検索を使用し、最適性を保証します。ヒューリスティックも一貫性がありO(動的プログラミング)であることを意味します(確認することはありませんが)。

プログラムは、指定した形式でSTDINから4行を読み取り、指定した形式で結果をSTDOUTに出力します。

from heapq import heappush,heappop
from itertools import combinations
N,E,S,W=range(4)
L="L"
R="R"
T="S"
d=[{L:E,R:W,T:S},{L:S,R:N,T:W},{L:W,R:E,T:N},{L:N,R:S,T:E}]
b=set([(N,S,W,E),(N,S,E,W),(S,N,W,E),(S,N,E,W),(E,W,N,E),(N,S,W,N),(S,N,E,S),(W,E,S,W)])
for x in list(b):b.add(x[2:]+x[:2])
def v(*a):return a[1]!=a[3] and a not in b
i=lambda:raw_input()+'\n'
i=map(lambda l:map(lambda e:("NESW"[l[0]],d[l[0]][e]), l[1]),enumerate((i()+i()+i()+i()).split()))
q=[]
heappush(q,(0,[],i))
while q:
    h,a,n=heappop(q)
    m=sum(map(bool,n))
    if m==0:
        print "\n".join(a)
        break
    for r in range(4,0,-1):
        f=False
        for c in combinations(range(4),r):
            l=True
            for i in c:
                if not n[i]:
                    l=False
                    break
            if not l:continue
            l=True
            for x,y in combinations(c,2):
                if not v(x,n[x][0][1],y,n[y][0][1]):
                    l = False
                    break
            if l==False:continue
            f=True
            e=list(n)
            for i in c:e[i]=e[i][1:]
            heappush(q,(m-r+min(map(len,e)),a+["".join([n[x][0][0] for x in c])],e))
        if f:break

使用例:

$ time echo "RRLLSSRLSLLSSLRSLR\nRLSLRLSLSSRLRLRRLLSSRLR\nRLSLRLRRLSSLSLLRLSSL\nLLLRRRSSRSLRSSSSLLRRRR" | python 4way.py
NES
NEW
NSW
NS
NS
ESW
NS
NES
NEW
NS
NES
NSW
NS
NS
NSW
NW
NS
NS
NS
EW
ES
SW
EW
EW
SW
ES
EW
EW
EW
EW
E
EW
EW
EW
EW
EW
E
EW
echo   0.00s user 0.00s system 38% cpu 0.002 total
python 4way.py  0.02s user 0.01s system 90% cpu 0.030 total
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.