Uma placa de 2D irá conter os seguintes objetos:
^
,>
,v
, Ou<
: Um laser emissor voltado para cima, direita, para baixo ou para a esquerda, respectivamente. Pode haver mais de um. Os lasers viajam em linha reta no espaço vazio (o espaço vazio é representado por um ponto.
). Os lasers não passam pelos emissores.*
: Um alvo. Lasers passam por alvos. Pode haver mais de um.
O quadro também pode conter os seguintes objetos:
@
: Uma parede sólida. O laser não passará por aqui.\
: Um refletor inclinado para a esquerda . Altera a direção dos lasers de acordo com a tabela a seguir:Direction laser is travelling Direction of laser after hitting reflector Up Left Right Down Down Right Left Up
Deve ser bastante intuitivo sobre como os refletores funcionam. Imagine-os como um espelho de dupla face real e as instruções devem ser claras.
/
: Um refletor inclinado para a direita . Altera a direção dos lasers de acordo com a tabela a seguir:Direction laser is travelling Direction of laser after hitting reflector Up Right Right Up Down Left Left Down
1
,2
,3
...9
: Um portal . O número indica o canal do portal - haverá exatamente dois portais do mesmo canal (por exemplo, não haverá três1
). O portal altera a posição dos lasers para a posição do outro portal do mesmo canal. Por exemplo:> 1 @ 1 *
O laser atingirá o alvo porque, quando atingir o primeiro
1
, é teleportado para o segundo1
do outro lado. Os lasers mantêm a mesma direção em que estavam antes.Um portal não teleporta o laser para um portal de um canal diferente (ou seja, a
1
não teleporta o laser para a9
.
Seu programa receberá uma representação 2D da placa como entrada. A prancha sempre terá formato retangular. A saída deve ser True
se todos os alvos tiverem lasers passando por eles ou False
não.
Aqui estão alguns casos de teste:
Entrada
>....\ ..*... >./../ ..*...
Saída
True
Entrada
>..........\ 1........../ 2..........1 3..........2 4..........3 5..........4 6..........5 7..........6 8..........7 9..........8 *..........9
Saída
True
Entrada
>.@............* >..@...........* >...@..........* >....@.........* >.....@........* >...*..@........ >.......@......*
Saída
False
Entrada
../\. >./**
Saída
False
Entrada
/.......*.......\/3..... @..............//\.\.... *.............2\.1\/\... \..............///.....< .........*...//\\/.....\ >.............\.1.///.4. 4.......*/...\2\/3/\/..^
Saída
True
Entrada
vvvvvvvvvvvvvvvvv \\\\\\\\\\\\\\\\\ ///////////////// \\\\\\\\\\\\\\\\\ ///////////////// \\\\\\\\\\\\\\\\\ ///////////////// *****************
Saída (observe o alvo na extrema direita)
False
Respostas:
Python,
310302287278277260Não é radicalmente diferente do post existente em Python, mas tem um ou dois truques notáveis, eu acho.
Ele também lida com entradas "não termináveis", comoEDIT : Opa! emissores bloqueiam lasers.1>1
.t
pega uma lista de strings (as linhas de entrada) e retorna um resultado booleano.Aqui está um bom gif do código sendo jogado para baixo:
EDIT : Awsome gif cortesia de Will. Obrigado Will!
fonte
1>1
terminará. Não consegui encontrar algo que não terminasse, embora não tenha me esforçado muito e assumido que isso não acontece na minha implementação. É claro que reconsiderarei se alguém puder apresentar uma..find(d)
retornar -1 se não for encontrado. Se você remover aif-1<d:
instrução e, em vez disso, fazê-loj+=[-1,1,w,-w,-i][d]
na parte superior do loop while, um -1 não encontrado passará a adicionar o último elemento nessa matriz aj
, que faráj
0, que sabemos que é@
...?Perl, 647
Esta é a minha primeira tentativa de golfe com código, e estou um pouco envergonhada por nem ter conseguido a pontuação C #, mas achei que seria interessante (ou divertido, ou apenas masoquista) fazer a coisa toda como um série de substituições regex. (Também achei que seria divertido atualizar meu Perl, mas no final lamentava profundamente não implementá-lo em Ruby ou Python.)
Eu não fiz muitos testes, mas acho que deve lidar com todos os casos.
A grade é inserida via STDIN. Deve haver pelo menos uma nova linha na entrada (ou seja, uma única linha sem uma nova linha não funcionará).
Explicação: o código atualiza iterativamente a cadeia de grade à medida que os lasers passam por ela.
-
representa um laser horizontal,|
um laser vertical,+
lasers cruzados,K
um\
espelho com um laser quicando no topo,k
um/
espelho com um laser quicando no fundo,Z
um\
espelho com um laser quicando no fundo eW
um/
espelho com um laser quicando no fundo o topo.%
é um/
espelho com lasers de ambos os lados, enquantoX
é um\
espelho com lasers de ambos os lados. (Eles diferenciam maiúsculas de minúsculas. Tentei escolher letras que pareçam um pouco apropriadas - por exemplo,k
eK
são escolhas um tanto óbvias - mas, infelizmente, o efeito realmente não é tão útil. Eu realmente deveria colocar essas informações em uma tabela, mas estou exausto agora.)O manuseio dos portais da mesma maneira (ou seja, atribuir a cada dígito um conjunto de caracteres extras com base nas possíveis posições do laser de entrada / saída) exigiria 144 caracteres (incluindo o original 9); portanto, quando um laser atinge um portal de "entrada", Eu adiciono o caractere de portal "output" ao conjunto de caracteres que emitem um laser na direção correta. (Isso requer diferenciação entre portais de entrada e saída; usei as letras
qwertyuio
para isso.)Um pouco sem golfe, com instruções de impressão para que você possa ver as substituições acontecendo (cada substituição representa uma "rodada" de progressão do laser) e com o
g
sinalizador adicionado ao principals///
para que não ocorra tantas iterações:fonte
Python 338
351Minha versão não minificada, na verdade, traça os caminhos do laser na placa, o que é bastante:
fonte
C # -
515414400 bytesPrograma C # completo, nenhuma saída agradável como a de Will. Funciona seguindo o caminho do laser para cada emissão individual e mantendo uma matriz de quais células visitamos, para que possamos verificar se visitamos todas as estrelas no final. Editar: distribuiu um grande número de bytes, criando tudo 1D e usando um caractere em vez de um int para armazenar o caractere atual
O w0lf me lembrou que eu tinha um loop for subutilizado bem no meio do meu código, então achei melhor fazer um último esforço e colocá-lo em funcionamento, e agora estou no número mínimo absoluto de suspensórios. Não pretendo gostar do colapso do segundo loop for, o código está horrivelmente desordenado agora, mas salvou alguns bytes. No processo, reescrevi a manipulação do portal. Eu também encontrei um método mais curto para executar a "movimentação" com operação condicional aninhada em vez de agregada.
Código de golfe:
Menos código de golfe:
O novo código de manipulação de portal utiliza o fato de que a função String.IndexOf retorna -1 (felizmente, char não encontrado) se você solicitar que ele comece a procurar 1 caractere além da string (lança uma exceção se você solicitar que inicie mais além). Isso foi novidade para mim, mas foi muito conveniente nesse caso.
fonte
m+=(d>0?d-2:0)+(d<3?d-1:0)*W;
e enfiá-lo nafor
, como este:for(char c;i-->0;m+=(d>0?d-2:0)+(d<3?d-1:0)*W)
. Dessa forma, você salvará um caractere, porque perderá um ponto e vírgula.