Resolver um cruzamento de tráfego


26

A tarefa

Escreva um programa ou função que adote uma estrutura de interseção de tráfego e produza a sequência na qual os veículos passarão.

A saída deve conter, no máximo, quatro linhas com o seguinte formato #. x->y\n, em que #é um número de número de sequência, seguindo-se a ponto ., xe ysão caracteres ["N", "E", "S", "W"]. Eles devem ser separados por caracteres ->. Se você não retornar uma matriz de cadeias, cada linha deverá terminar com um \n(caractere de nova linha) ou equivalente ao seu sistema.

A entrada deve assumir o seguinte formato:

  • Parte 1: quatro caracteres, cada um com a estrada de destino para as estradas de origem na ordem N, E, S, W (no sentido horário). Os caracteres são permitidos N, S, W, Eou . Espaço significa que não há veículo em determinada estrada. Por exemplo, string S WEsignifica que N veículo deseja ir para o sul, espaço significa que não há veículo E, Wsignifica que S deseja ir para o oeste, Esignifica que o oeste deseja ir para o leste.
  • Parte 2 - um espaço ou uma única letra que significa qual é o veículo de emergência.
  • Parte 3 - dois caracteres que determinam quais duas estradas têm prioridade (por exemplo, NEsignifica que o norte e o leste têm prioridades mais altas que o sul e o oeste). Se for mais fácil para você, você pode pegar estradas de menor prioridade (nesse caso SW).

Em uma situação insolúvel que estão autorizados a devolver uma cadeia de uma linha que é claro para o usuário, como unsolvable, no solutione similar. Os usuários de JavaScript podem ter uma undefinedconstante interna.

Este é um código-golfe, então a resposta mais curta em bytes vence.

As regras de trânsito

Observe que algumas das regras podem não seguir as regras de tráfego do seu país. Alguns deles foram simplificados para facilitar o desafio. Não use esta pergunta como um guia para o sistema de tráfego da vida real.

  1. Para o desafio, você tem permissão para usar apenas o tráfego do lado direito.
  2. O cruzamento de tráfego consiste em exatamente quatro estradas que se encontram em um ponto. Eles são marcados N(como para "Norte"), S, W, E. Essas letras devem ser usadas em vez de xe yno exemplo de saída acima.

Uma interseção

  1. Em cada estrada, há no máximo um veículo. Não é garantido que exista um veículo em cada estrada. Cada veículo pode dirigir em qualquer uma das quatro direções, ou seja. vire à esquerda, vire à direita, siga em frente ou faça uma inversão de marcha .

Possíveis destinos do veículo S

  1. Se os caminhos de dois veículos não se cruzam (eles não colidem), eles podem seguir no mesmo momento. Os caminhos não colidem, se dois veículos (a lista pode não estar completa, mas isso é intencional, apenas para lhe dar uma pista):
    • vêm de direções opostas e ambas seguem em frente, ou pelo menos uma delas vira à direita,
    • vêm de direções opostas e ambos vire à esquerda,
    • vêm de direções opostas e um deles gira em qualquer direção ou faz a inversão de marcha, enquanto o outro faz a inversão de marcha,
    • provenientes de direções ortogonais, uma à esquerda está virando à direita e a outra não faz a inversão de marcha

      Alguns exemplos de não colidir caminhos abaixo. Observe que, no terceiro desenho, qualquer caminho de N colidirá com o caminho de E, mesmo que N faça uma inversão de marcha.

insira a descrição da imagem aqui insira a descrição da imagem aqui

insira a descrição da imagem aqui insira a descrição da imagem aqui

  1. Se dois caminhos colidem, é necessário usar outras regras. Se dois veículos estiverem na mesma estrada prioritária (veja abaixo), o direito de passagem será concedido ao veículo que:
    • é vem da estrada do lado direito, se vierem de direções ortogonais
    • vira à direita se o outro vira à esquerda
    • vai reto ou vira à direita se o outro fizer uma inversão de marcha.

      Nos dois exemplos abaixo, o veículo E tem direito de passagem sobre o veículo S.

insira a descrição da imagem aqui insira a descrição da imagem aqui

No exemplo abaixo, primeiro vai W, depois N, depois E e, por último, S.

insira a descrição da imagem aqui

Nesse caso em particular, a saída do seu programa deve ser:

1. W->S
2. N->S
3. E->S
4. S->S
  1. Todos os motoristas usam indicadores de direção e sabem para onde todos os outros desejam ir (por simplicidade, assumimos que é possível distinguir entre a curva à esquerda e a inversão de marcha).

  2. Às vezes, as estradas recebem sinais de prioridade, que são mais importantes que as regras acima. Uma estrada com prioridade mais alta tem um sinal de prioridade ( imagem do sinal de prioridade ). Se a estrada prioritária não for reta, também serão utilizados sinais adicionais, como este . As estradas com prioridade mais baixa têm um sinal de rendimento ou um sinal de parada (eles são equivalentes). Nenhuma ou exatamente duas estradas diferentes terão prioridade mais alta. O usuário do seu programa deve poder informar quais estradas têm prioridades mais altas (ou mais baixas).

  3. Um veículo que sai da estrada com maior prioridade tem o direito de passagem sobre um veículo proveniente da estrada de menor prioridade, mesmo que esteja do lado esquerdo.
  4. Se os caminhos de dois veículos vindos das estradas com a mesma prioridade colidirem, as regras acima do lado direito estarão ativas.

    No exemplo abaixo, as estradas S e W têm sinais de prioridade, o que significa que os veículos em N e E devem dar o caminho. O veículo S tem prioridade sobre o veículo W, porque está do lado direito, o que acontece primeiro. Então vai W, porque está na estrada de maior prioridade que E. O veículo N tem uma saída de E, porque está do lado direito. Como o último vai E.

insira a descrição da imagem aqui

Nesse caso em particular, a saída do seu programa deve ser:

1. S->W
2. W->N
3. N->S
4. E->W
  1. É possível que um (e não mais) veículo seja um veículo de emergência , que tenha a prioridade, independentemente de qual direção ele vem ou vai, e que sinal tem (sempre o primeiro). O programa deve permitir que o usuário entre em qual veículo é um veículo de emergência. Considerando que no último exemplo N é um veículo de emergência, N vai primeiro, depois S, W e como o último E.

Para este caso específico com um veículo de emergência em N, a saída do seu programa deve ser:

1. N->S
2. S->W
3. W->N
4. E->W
  1. Se dois veículos puderem ir no mesmo momento (seus caminhos não colidem e não precisam dar lugar a outros veículos), seu programa deve descobrir isso e devolvê-los como tendo o mesmo número de sequência

    No exemplo abaixo, os caminhos de N e E, bem como E e S ou W e E, não colidem. Como S tem que dar lugar a N e W dá lugar a S, S não pode ir simultaneamente com E etc. O N e E podem. Então, a princípio, N e E andam juntos, depois S e W como o último.

insira a descrição da imagem aqui

A saída adequada do seu programa deve ser:

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

Você é livre para escolher a ordem das linhas 1( N->W / E->Eé equivalente a E->E / N->W)

  1. Às vezes, o tráfego pode levar a uma situação insolúvel, que não permite que nenhum veículo saia. Na vida real, isso é resolvido quando um dos motoristas renuncia voluntariamente ao seu direito de passagem. Aqui, seu programa deve produzir unsolvableetc., como mencionado na primeira parte da pergunta.

    Abaixo está um exemplo de situação insolúvel. E deve dar lugar a W, W deve dar lugar a S e S deve dar lugar a E.

insira a descrição da imagem aqui


3
Eu acho que um formato de entrada consistente deve ser definido. "A entrada pode ter qualquer estrutura que você quiser" é uma grande bandeira vermelha. A entrada pode ser a solução?
Hobbies de Calvin

@ Calvin'sHobbies Atualizei a pergunta
Voitcus 4/15

Alguma chance de obtermos um exemplo de entrada / saída para 1-2 casos?
Charlie Wynn

Portanto, a pergunta (e eu estou assumindo a solução) assume que as estradas em questão são de volante à direita?
Tersosauros 27/03

É exatamente assim que o Google Cars funciona
coredump 06/06

Respostas:


8

Q, 645 bytes

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);}

COMENTÁRIOS

Definitivamente, não é um código curto (nem simples). Pode ser (severamente) compactado, mas é deixado como exercício para o leitor (dediquei muito tempo a esse problema).

Eu incluí a solução comentada com várias linhas, mas assumo novas linhas como 1 byte e descarto os comentários (de / para o final da linha) para contar o tamanho

A principal dificuldade é entender completamente todas as regras. A otimização antecipada do comprimento do código é incompatível com o desenvolvimento de uma solução para um problema complexo. Nem a abordagem de baixo para cima ou de cima para baixo lida bem com códigos ilegíveis.

Por fim, desenvolvi uma tabela de decisão (matriz de conflito) com 16 linhas e 16 colunas (para cada direção combinada com cada volta possível). Os valores dos itens são 0 (compatibilidade), 1 (preferência pela linha) ou 2 (preferência pela coluna). Satisfaz todos os testes, pois não tenho certeza de que todas as situações possíveis estão bem cobertas

O arquivo de origem deve ter extensão k. Inicie o intérprete interativo (gratuito para uso não comercial, kx.com) e avalie imediatamente (conforme mostrado no parágrafo 'teste')

TESTE

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

EXPLICAÇÃO

A estrutura base é a 'matriz de precedência'

   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

Significado (por exemplo)

  • m[NW][SE] tem valor 0 (ambos os movimentos são compatíveis - simultâneos)
  • m[EW][SN] tem 1 valor (EW tem prioridade sobre SN) NOTA.- outros fatores de prioridade podem alterar esta frase (veículos de emergência, via prioritária, etc.)
  • m[NE][SE] tem 2 valor (SE tem prioridade sobre NE) NOTA.- outros fatores de prioridade podem alterar esta frase (veículos de emergência, via prioritária, etc.)

A matriz pode ser construída usando quatro tipos de submatriz (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

A matriz é complementada com uma função que atribui uma prioridade a cada movimento. Essa função leva em conta veículos de emergência, estradas prioritárias, direções ortogonais, tipo de curva e veículos que vêm da direita

Classificamos os movimentos por prioridade e aplicamos os valores da matriz. A submatriz resultante inclui conflitos e prioridade de cada movimento.

  • analisamos casos insolúveis (conflitos mútuos)
  • caso contrário, selecionamos o item mais prioritário e todos os movimentos compatíveis com ele e não incompatíveis com os movimentos incompatíveis anteriores, e criamos um conjunto de movimentos que podem ocorrer simultaneamente
  • Escreva esse conjunto de movimentos e repita o restante dos candidatos
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.