Brincando com robôs para crianças - Qual letra chegarei?

12

TL; DR: Dada uma matriz de caracteres e um robô na posição inicial da matriz, escreva um algoritmo que possa ler uma sequência com movimentos ( Fpara "avançar", R"girar 90 graus à direita" e L"girar 90 graus" esquerda ") e calcule a posição final do robô. Mais detalhes no texto completo.

Temos em casa um dispositivo programável muito simples para crianças: um pequeno veículo com botões para fazer o veículo avançar, virar 90 graus à esquerda ou virar 90 graus à direita. Algo semelhante a isso:

Veículo do mouse

Também temos um tapete de espuma com letras como esta:

Jogando o tapete

O objetivo de tudo isso é ensinar às crianças o alfabeto e os rudimentos da programação, todos de uma vez.

O desafio

Suponha que organizamos aleatoriamente nosso tapete de espuma assim:

+---+---+---+---+---+---+---+
| E | R | L | B | I | X | N |
+---+---+---+---+---+---+---+
| O | A | Q | Y | C | T | G |
+---+---+---+---+---+---+---+
| F | W | H | P | D | Z | S |
+---+---+---+---+---+---+---+
    | K | V | U | M | J |   
    +---+---+---+---+---+
            |   |
            +---+

Suponhamos também que modificamos o veículo para que, quando programamos um comando "avançar", o veículo avance exatamente o tamanho de um quadrado no tapete. Portanto, se o veículo estiver na Upraça e for para o norte, ele para exatamente na Ppraça.

Todas as instruções são fornecidas ao veículo antes de começar a se mover e são elas:

  • F: O veículo avança para a próxima praça.
  • R: O veículo gira 90 graus no lugar certo (sem movimento adicional).
  • L: O veículo vira 90 graus à esquerda em seu lugar (sem movimento adicional).

Uma vez que as instruções são dadas, você pode pressionar o botão "GO" e enviar o veículo para uma determinada posição, pois seguirá todas as instruções na ordem especificada. Assim, você pode pedir ao garoto para inserir as instruções necessárias para que o veículo vá para uma determinada carta.

Você deve escrever o programa / função mais curto que processa um string(parâmetro de entrada) com um conjunto de instruções e calcula a letra em que o veículo para (saída string).

Detalhes:

  • O veículo sempre começa no quadrado em branco na parte inferior e voltado para o norte (em direção ao Uquadrado).
  • A cadeia de entrada irá conter apenas as letras F, R, Le G(para o botão "Go"). Você pode usar letras minúsculas para o tapete e as instruções, se preferir.
  • O algoritmo deve obedecer a todas as instruções na string antes da primeira G(todas as instruções depois disso são ignoradas quando o veículo começa a se mover).
  • Se o veículo sair do tapete a qualquer momento (mesmo que a sequência de entrada não tenha sido completamente processada), o algoritmo deverá retornar a sequência Out of mat.
  • Caso contrário, o algoritmo deve retornar a carta em que o veículo parou. O ponto de partida conta como um caractere (ou uma sequência vazia).

Exemplos:

Input: FFG
Output: P

Input: FRFRFG
Output: Out of mat

Input: RRFFG
Output: Out of mat

Input: FFFRFFLFG
Output: X

Input: FFFRFFLF
Output:      <-- Nothing or a whitespace (the robot has not started moving)

Input: FFFRRFFFG
Output:      <-- Nothing or a whitespace (the robot has returned to the starting point)

Input: RRRRRLFFFLFFRFRFGFFRRGRFF
Output: L    (Everything after the first G is ignored)

Este é o , por isso pode ganhar o programa mais curto para cada idioma!

Charlie
fonte
1
Próximo passo: mesma coisa, mas com a configuração do tapete como entrada para a cadeia, com @sendo a posição inicial e espaços que são fora do tapete, então esta configuração seria ERLBIXN\nOAQYCTG\nFWHPDZS\n KVUMJ \n @(com espaçamento diferente, SE estraguei tudo)
Stephen

Respostas:

3

JavaScript (ES6), 194 176 169 163 bytes

Salvou alguns bytes graças a @Luke e @Arnauld.

s=>(p=35,d=3,t='ERLBIXN1OAQYCTG1FWHPDZS11KVUMJ11111 11',[...s].every(i=>i=='L'?d--:i>'Q'?d++:i<'G'?+t[p+=[1,8,-1,-8][d%4]]||!t[p]?p=1/0:p:0)?'':t[p]||'Out of mat')

Ungolfed:

s=>(
  p=35,
  d=3,
  t='ERLBIXN1OAQYCTG1FWHPDZS11KVUMJ11111 11',
  [...s].every(i=>i=='L'?d--:
                  i<'Q'?d++:
                  i<'G'?+t[p+=[1,8,-1,-8][d%4]]||!t[p]?p=1/0:p:
                  0
              )?'':
               t[p]||'Out of mat'
)

f=
s=>(p=35,d=3,t='ERLBIXN1OAQYCTG1FWHPDZS11KVUMJ11111 11',[...s].every(i=>i=='L'?d--:i>'Q'?d++:i<'G'?+t[p+=[1,8,-1,-8][d%4]]||!t[p]?p=1/0:p:0)?'':t[p]||'Out of mat')

console.log(f('FFG')); //P
console.log(f('FRFRFG')); //Out of mat
console.log(f('RRFFG')); //Out of mat
console.log(f('FFFRFFLFG')); //X
console.log(f('FFFRFFLF')); //(space)
console.log(f('FFFRRFFFG')); //(space)
console.log(f('RRRRRLFFFLFFRFRFGFFRRGRFF')); //L
console.log(f('FFFFFRRFG')); //Out of mat

Rick Hitchcock
fonte
1
Você pode salvar 3 bytes substituindo falsepor!1
Luke
Obrigado, @ Lucas. Na verdade, posso salvar um monte de bytes removendo completamente o teste "G". Se não for "L", "R" ou "F", pode-se supor que seja "G" (a menos que "G" esteja ausente). De qualquer maneira, o everymétodo lida com isso.
Rick Hitchcock
Aqui está uma solução para 165 bytes:(s,p=35,d=3,t='ERLBIXN1OAQYCTG1FWHPDZS11KVUMJ11111 11')=>[...s].every(i=>i=='L'?d--:i=='R'?d++:i=='F'?+t[p+=[1,8,-1,-8][d%4]]||!t[p]?p=1/0:1:0)?'':t[p]||'Out of mat'
Luke
Não sei como isso me leva a 165 bytes (?) Mas certamente não preciso de uma variável separada para a [1,8,-1,-8]matriz, obrigado!
Rick Hitchcock
Ops, devo ter citado incorretamente, é 171. Também removi um espaço que você não precisa, que ainda está na resposta atual (é o último espaço).
28617 Luke
2

Python 2 , 235 bytes

x=0;y=1;a=4;b=3
p='ERLBIXN','OAQYCTG','FWHPDZS','aKVUMJ','aaa '
r=''
for i in input():
 if'G'==i:r=p[a][b];break
 elif'G'>i:
  b+=x;a-=y;
  if(-1<a<5)-1or(''<p[a][b:]<'a')-1:r='Out of mat';break
 else:x,y=[[y,-x],[-y,x]][i<'R']
print r

Experimente online!

ovs
fonte
2

Python 3 , 226 231 241 bytes

Segunda edição; deve funcionar agora. Novamente, muita otimização a ser feita.

n=input();s="0ERLBIXN00OAQYCTG00FWHPDZS000KVUMJ000000 00000";d=1;c=40;i=0;w=[-1,-9,1,9]
while n[i]!="G"and c>=0:
 if n[i]=="F":c+=w[d]
 else:d=[d+[-1,3][d<0],-~d%4][n[i]=="R"]
 i+=1
print(["Out of mat",s[c]][c in range(len(s))and s[c]!="0"])

Experimente online!

Fedone
fonte
0

Wolfram Language / Mathematica, 300 bytes

p=Re[(1-7I)#[[1]]]&;d=Drop;t=Throw;s=Switch;s[#,0,"Out of mat",_,StringPart["000 0000KVUMJ0FWHPDZSOAQYCTGERLBIXN",p@#]]&@Catch@Fold[If[MemberQ[d[d[Range[4,35],{2,5}],{7}],p@#],#,t@0]&@(s[#2,"F",#+{#[[2]],0},"R",#{1,-I},"L",#{1,I},_,t[#]]&)[#1,#2]&,{4,I},If[StringFreeQ["G"]@#,{"G"},Characters@#]&@#]&

Ungolfed:

p = Re[(1 - 7 I) #[[1]]] &;
d = Drop;
t = Throw;
s = Switch;
s[#,
    0, "Out of mat",
    _, StringPart["000 0000KVUMJ0FWHPDZSOAQYCTGERLBIXN", p@#]] &@
  Catch@
  Fold[
    If[MemberQ[d[d[Range[4, 35], {2, 5}], {7}], p@#], #, 
        t@0] &@(s[#2, "F", # + {#[[2]], 0}, "R", # {1, -I}, 
          "L", # {1, I}, _, t[#]] &)[#1, #2] &,
    {4, I},
    If[StringFreeQ["G"]@#, {"G"}, Characters@#] &@#] &
chuy
fonte