Siga instruções incompletas

21

Um amigo seu deu instruções para o melhor restaurante da cidade. É uma série de curvas à esquerda e à direita. Infelizmente, eles esqueceram de mencionar por quanto tempo você precisa seguir em frente entre esses turnos. Felizmente, você tem um mapa de ruas com todos os restaurantes. Talvez você possa descobrir qual restaurante eles queriam dizer?

Entrada

O mapa é fornecido como uma grade retangular de caracteres ASCII. .é uma estrada, #é um edifício, Apara Zsão os vários restaurantes. Você começa no canto superior esquerdo, indo para o leste. Exemplo:

.....A
.#.###
B....C
##.#.#
D....E
##F###

As instruções do seu amigo serão fornecidas como uma sequência (potencialmente vazia) ou uma lista de caracteres contendo Ls e Rs.

Saída

Você pode percorrer qualquer caminho que corresponda às curvas esquerda e direita na sequência de entrada, desde que você dê pelo menos um passo à frente antes de cada uma delas, bem como no final. Em particular, isso significa que se a sequência começar, Rvocê não poderá ir para o sul imediatamente na coluna mais à esquerda. Isso também significa que você não pode girar 180 ° no local.

Você não pode andar por prédios ou restaurantes, exceto aquele que você alcança no final. Você pode assumir que o canto superior esquerdo é a ..

Você deve exibir todos os restaurantes que podem ser acessados ​​com as instruções do seu amigo, como uma sequência ou lista.

Você pode assumir que as instruções levarão a pelo menos um restaurante. Por exemplo, um único Lseria inválido para o mapa acima.

Alguns exemplos para o mapa acima:

<empty> A
R       F
RR      B,D
RL      C,E
RLRL    E
RLLR    C
RLLL    B
RLRR    D
RLRRRR  A,C
RLLLRLL B

Observe em particular que Rnão chega B.

Você pode escrever um programa ou função, recebendo entrada via STDIN (ou alternativa mais próxima), argumento da linha de comando ou argumento da função e emitindo o resultado via STDOUT (ou alternativa mais próxima), valor de retorno da função ou parâmetro da função (saída).

Aplicam-se as regras padrão de .

Casos de teste adicionais

Aqui está um mapa maior, cortesia de Conor O'Brien (que modifiquei um pouco):

.......Y..........................######
.####.....#.##....##..######....#.###.##
B.........#.##.#..##....##...##.#.#P...#
.#.#####..#.##..#.##....##.#....#.####.#
.#.#...C..#.##...G##..#.##.#....#.#....#
.#.#.#.#..#.####.###.#..##.#....#.#.NO.#
.#.#A#.#..#.##...F###...##.#.##.#......#
.#.###....#.##....##....##.#....###....#
.#.....##...##....##...D##........###R.#
.#.##..##...##E...##..######....####...#
.....X....#.#.....................##S.T#
###########.###########M############...#
#................................###.#.#
#.#########.########.######.#.######.#.#
#......V#.....######.IJ...........##.#.#
#########.###......ZH############L##.#.#
#########.##########.###############.#.#
####K##...##########.#....#..........#.#
####....########U......##...#######Q.#.#
#####################################W.#

E aqui estão algumas listas selecionadas de direções e seus resultados esperados:

<empty>                                 Y
RR                                      B
RLL                                     Y
RLRR                                    B,C,X
RLLLRRR                                 G
RLRLRLRL                                I,Z
RLLRRRLRRLRR                            C,D,F,G,Y
RLRRLLRLLLRL                            B,C,Y
RLLRRLRRRLLLL                           F,M,N,O,Y
RLRRLLLRRRRLLLL                         F,M,Y
RLRRLRRRRRRRRRR                         E,F,Y
RLRRRLLLRLLRRLL                         M,N,O
RLLRRLRRLRLRLRRLLR                      E,U
RLRLLRLRRLRRRRRLRL                      F,G,I,Z
RLLRRLLRLLRRRLRRLLRR                    W
RLLLRRRLRRLLLLLRLLLLLL                  D,G,X
RLRLLRLRRLRLRRRLRLLLRR                  B,C,E,J,X
RLRLRLLLLRLRRRRRRLRLRRLR                Y
RLRLRRRLRLLLLRLRRLLLLRLLRRL             E,M,X
RLRLLLRRRLLLRLLRLLRLRRLRLRR             B,E,F,K
RLRRRLLLLLLLLLLLLLLLRRRRLLL             A,B

Pergunta de bônus: existe uma entrada que resulta em apenas I ou somente U ? Se sim, qual é o caminho mais curto?

Martin Ender
fonte

Respostas:

17

Perl, 150 149 146 145 141 140 138 136 135 133 130 126 125 124

Adicionado +7 para -F -Xn0i

Uma tentativa inicial.

Corra com o mapa em STDIN e as direções após a opção -i, por exemplo

perl -F -Xn0iRL incomplete.pl
.....A
.#.###
B....C
##.#.#
D....E
##F###

Feche o STDIN com ^Dou o ^Zque funciona no seu sistema operacional.

incomplete.pl:

%P=0;$^I=~s``{%;=!/
/;%P=map{$_|=$F[$^H=$_+=(1,@+,-1,"-@+")[$d&3]]=~/(\w)|#|^$/*~!\$;{$1}}(%P)x@F}$d-=B&$'^u`eg;print%

Substitua ^ H pelo caractere de controle literal para obter a pontuação fornecida

Pergunta bônus:

  • Não há entrada que resulte em apenas I
  • A entrada mais curta que resulta em única UéRLLRRLLRLRLRRLRRLRLRLRRLLR
  • A entrada mais longa necessária para resultar em um conjunto único é o RLLRRRLRLRLLLRRLRLLLLLRRRLLRRRLLLLLLLRRLRRRRque forneceB O R
Ton Hospel
fonte
4
O Ton Hospel? :)
Lynn
14
Existe apenas um alienígena com esse nome
Ton Hospel
2
@TonHospel É uma honra tê-lo aqui.
Msh210
8

Python 2, 180 177 168 163 161 158 bytes

def a(v,o,c=0,A=0,d='.',O={0}):
 while'.'==d:w=v.find('\n');c+=[1,~w,-1,w+1][A%4];d=v[c];o>v<a(v+' '*w,o[1:],c,ord(o[0])-~A,d);d>v>o<O.add(d)
 return`O`[9::5]

Parâmetro vé o mapa como uma string; oé a LRstring.

Mitch Schwartz economizou 2 3 10 lotes de bytes. Obrigado!

Eu salvei dois bytes configurando O={0}e retornando `O`[9::5], o que pode não ser muito portátil: hash(0) == 0suponho que , creio, porque isso faz com que a ordem dos elementos repr(O)seja

set([0, 'A', 'B', 'C'])

e cortar criativamente essa corda me dá a resposta.

Lynn
fonte
Eu acho que isso sofre uma explosão exponencial se você executá-la em uma grade grande quase vazia com cordas de giro longas
Ton Hospel
Ah, sim, é um desastre de desempenho absoluto. Porém, funciona para as grades de exemplo!
Lynn
1

C ++ 465

C ++ é tão detalhado ...

#include <vector>
#include <iostream>
using namespace std;
#define M m[y][x]
#define A if(M!=46)break
vector<string>m;char n[99];int r(int x,int y,int z,const char *d){for(;;){if(z%2)y=y-2+z;else x=x+1-z;if(y<0||y>=m.size()||x<0||x>=m[y].size())break;if(*d){A;r(x,y,(*d==82?z+3:*d==76?z+1:z)%4,d+1);}else{if(M>64&&M<91)n[M]++;A;}}}int main(int c,char**v){string l;while(getline(cin,l))m.push_back(l);r(0,0,0,c>1?v[1]:"");for(char j=0;j<99;j++)if(n[j])cout<<j<<" ";}

Vou tentar encurtar ainda mais. Sugestões são bem vindas.

Jerry Jeremiah
fonte