Escola de Marshalling de aeronaves

8

Dada uma sequência que representa uma série de sinais manuais da aeronave , escreva uma função ou programa para calcular a posição final de uma aeronave seguindo esses sinais.

NB: A co-ordenadas em este desafio são representados como um par de coordenadas cartesianas, além de uma posição compasso: (x, y, h)onde xé a coordenada x, yé a coordenada y, e hé um de N, E, S, ou W.

Você começa com uma aeronave (0, 0, N)em uma grade imaginária, com os motores desligados. Sua entrada é uma sequência que contém pares de caracteres delimitados por vírgula, em que cada par representa um sinal de empacotamento. Você deve seguir cada sinal de empacotamento, por sua vez, e emitir as coordenadas na (x, y, h)forma da posição final da aeronave.

Se um sinal exigir que sua aeronave se mova, assuma que ele move uma unidade na direção requerida para cada sinal daquele tipo que recebe. Se um sinal exigir que sua aeronave gire, assuma que ele gire 90 graus na direção necessária para cada sinal daquele tipo que ele receber.

Uma aeronave não pode se mover se seus motores estiverem desligados. Se os motores da sua aeronave estiverem desligados e você receber um sinal de movimento / virada, não aplique o movimento / virada.

Signals

Cada sinal de empacotamento é representado por um par de caracteres. O primeiro do par representa a posição do braço esquerdo do oficial de justiça, do ponto de vista da aeronave , e o segundo o braço direito do mesmo ponto de vista . Este gráfico acessível de sinais pode ajudar.

o/  —  START ENGINES (no movement, no turn)
-/  —  CUT ENGINES   (no movement, no turn)
-~  —  TURN LEFT     (no movement, left turn)
~-  —  TURN RIGHT    (no movement, right turn)
~~  —  COME FORWARD  (forward movement, no turn)
::  —  MOVE BACK     (backward movement, no turn)
/\  —  NORMAL STOP   (no movement, no turn)

Esta não é a lista completa de sinais de organização, mas é tudo que você precisa para apoiar.

Entrada

Entrada é uma sequência delimitada por vírgula contendo pares de caracteres. Essa cadeia sempre será válida - você não precisa validar a entrada.

Resultado

Saída é um conjunto de coordenadas como descrito acima. Você pode retornar isso em qualquer formato conveniente - se o seu idioma suportar vários valores de retorno, você poderá usá-lo; Como alternativa, você pode usar uma string (os colchetes ao redor das coordenadas não são obrigatórios), matriz, tupla, lista ou qualquer outra coisa que achar conveniente. A única regra é que ele deve conter x, ye hvalores, nessa ordem.

Casos de teste

Input  —  Output
o/,~~,~~,~-,::  —  (-1, 2, E)
::,~-,o/,/\,~~,-~,~~,~~,~~  —  (-3, 1, W)
o/,::,-/,~~,o/,~-,~~,~~,~-  —  (2, -1, S)
o/,~-,~-,::,::,~-,~~,-~  —  (-1, 2, S)
~-,~-,o/,::,::,-/,~~,-~  —  (0, -2, N)
ArtOfCode
fonte
1
O que os motores de partida e de corte realmente fazem? Apenas esses movimentos entre os motores de partida e os motores de corte serão executados? Caso contrário, não vejo a relevância.
Level River St
@LevelRiverSt "Uma aeronave não pode se mover se seus motores estiverem desligados." Eu já passei por isso no texto.
ArtOfCode 3/16/16
se escrevermos uma função, podemos considerar a entrada como uma lista de instruções?
FlipTack # 3/16
@ Flp.Tkc Você pode mudar o desafio para facilitar? Não :)
ArtOfCode 3/16/16
Eu não sabia que o uso de uma função "dividida" embutida era tão desafiador. Ter um formato de entrada rígido no code-golf não é recomendado; o padrão é "pegue a entrada em qualquer formato conveniente".
FlipTack

Respostas:

2

Java 8, 505 bytes

Golfe (com a ajuda de @ masterX244 para raspar um grande pedaço)

class f{static boolean T(String u,String v){return u.equals(v);}public static void main(String[]a){java.util.Scanner q=new java.util.Scanner(System.in);String s=q.nextLine();int x=0;int y=0;int d=0;int[][]v={{0,1},{-1,0},{0,-1},{1,0}};int b=1;for(String r:s.split(",")){if(T(r,"o/")||T(r,"-/"))b=~1;if(b<0){if(T(r,‌​"~-"))d=(d+3)%4;if(T‌​(r,"-~"))d=(d+1)%4;i‌​f(T(r,"~~")){x+=v[d]‌​[0];y+=v[d][1];}if(T‌​(r,"::")){x-=v[d][0]‌​;y-=v[d][1];}}}Syste‌​m.out.println("("+x+‌​","+y+","+"NWSE".cha‌​rAt(d)+")");}}

Mais legível

class f {
    static boolean T(String u,String v){return u.equals(v);}
    public static void main(String[] a) {
        java.util.Scanner q=new java.util.Scanner(System.in);
        String s=q.nextLine();
        int x=0;
        int y=0;
        int d=0;
        int[][] val = {
                {0,1},  // N
                {-1,0}, // W
                {0,-1}, // S
                {1,0}   // E
        };
        int b=1;
        for (String r: s.split(",")) {
            // toggle b if either start or stop engine
            if(T(r,"o/") || T(r,"-/"))
                b=~1;
            if(b<0){
                // right
                if(T(r,"~-")) d=(d+3)%4;
                // left
                if(T(r,"-~")) d=(d+1)%4;
                // come forward
                if(T(r,"~~")) {
                    x+=val[d][0];
                    y+=val[d][1];
                }
                // move back
                if(T(r,"::")) {
                    x-=val[d][0];
                    y-=val[d][1];
                }
            }
        }
        System.out.print("("+x+","+y+","+"NWSE".charAt(d)+")");
    }
}
Bobas_Pett
fonte
alguns bytes livres: a classe contendo main () não precisa ser pública (consulte as dicas de golfe para java aqui) e vários espaços em branco que podem ser otimizados (qualquer coisa ao lado de símbolos não alfanuméricos pode ser removida). também false pode ser gravado como 0> 1
masterX244 3/16/16
Além disso: substituir o bool por um int e compará-lo por ser maior ou menor que zero eliminou alguns bytes também. (usando * = - 1 para alternar) no próximo comentário. E sempre usar print () sobre println quando você só precisa de uma linha emitidas
masterX244
class f{static boolean T(String u,String v){return u.equals(v);}public static void main(String[]a){java.util.Scanner q=new java.util.Scanner(System.in);String s=q.nextLine();int x=0;int y=0;int d=0;int[][]v={{0,1},{-1,0},{0,-1},{1,0}};int b=1;for(String r:s.split(",")){if(T(r,"o/")||T(r,"-/"))b*=-1;if(b<0){if(T(r,"~-"))d=(d+3)%4;if(T(r,"-~"))d=(d+1)%4;if(T(r,"~~")){x+=v[d][0];y+=v[d][1];}if(T(r,"::")){x-=v[d][0];y-=v[d][1];}}}System.out.print("("+x+","+y+","+"NWSE".charAt(d)+")");}}
masterX244
@ masterX244 thx Estou claramente um pouco familiarizado com isso. Ill adicionar na edição para impressão
Bobas_Pett
a importação também é um local para otimizar. para uma ou duas menções, uma referência totalmente qualificada em ambas é mais curta que a importação. (código i colado no comentário contém todos otimiza i encontrado)
masterX244
1

Befunge, 201 185 bytes

p10p2p3pv
~/3-*95~<v:+-"/"
  v!:-*53_v
 #_7-:v v0-1
vv!:-3_100>p
 _69*-:v NESW v+g01g
v v-*93_g10g\->4+4%10p
v<_100g >*:10g:1\-\2%!**03g+03p10g:2\-\2%**02g+02p
>>~65*`#v_2g.3g.10g9+5g,@

Experimente online!

O Befunge não possui um tipo de string, portanto, para facilitar a comparação dos sinais, cada par de caracteres é convertido em um número inteiro usando a fórmula (c1 - 45)/3 + c2 - 47. Isso pode significar que obteremos correspondências falsas em entradas inválidas, mas isso não importa se a entrada é garantida como válida.

O restante do código é baseado na manipulação de quatro "variáveis": o estado do mecanismo (1 ou 0), o cabeçalho (0 a 3 para NESW) e as posições x e y . Os cálculos para cada sinal são os seguintes:

Motor de partida: engine = 1
Corte o motor: engine = 0
Vire à esquerda: heading = (heading - engine + 4) % 4
Vire à direita: heading = (heading + engine) % 4
Movimento: (onde dir é 1 para frente e -1 para trás)
y += dir*engine*(1-heading)*!(heading%2)
x += dir*engine*(2-heading)*(heading%2)

Quando chegamos ao final da sequência de entrada, é apenas uma questão de gerar x , y e cabeçalho (convertido em um char com uma simples pesquisa de tabela).

James Holderness
fonte
1

Python 2.7.12, 295 bytes

from operator import*
l=[0,0]
m=[['N',[0,1]],['E',[1,0]],['S',[0,-1]],['W',[-1,0]]]
n=0
x=raw_input()
for c in x.split(','):
 if'o/'==c:n=1
 if'-/'==c:n=0
 if n:
    if'-~'==c:m=m[-1:]+m[:-1]
    if'~-'==c:m=m[1:]+m[:1]
    if'~~'==c:l=map(add,l,m[0][1])
    if'::'==c:l=map(sub,l,m[0][1])
print l+[m[0][0]]

O primeiro nível de recuo depois forusa um único \s. O recuo do segundo nível usa um único \t. (o wysiwyg é substituído \tpor vários espaços. Lembre-se disso ao testar o tamanho)

Eric
fonte
3
muitos espaços em branco estranhos que você pode remover aqui.
ArtOfCode 03/12
Não apenas espaço em branco, mas outras ineficiências fáceis de corrigir. Experimente as dicas de golfe em python para exemplos específicos.
Ad Hoc Garf Hunter
Observe que no code-golf você não precisa ter nenhum prompt de entrada: basta fazer isso raw_input().
FlipTack 31/03/19
Este código erros para mim na linha 15: TypeError: Argument to map() must support iteration(estou usando Python 2.7.12).
Clismique
@ Qwerp-Derp, acredito que corrigi o erro map ().
Eric
1

Python 2, 142 bytes

s=raw_input()
e=p=0;d=1
while s:exec'd-=e d+=e p+=1j**d*e e=0 0 e=1 p-=1j**d*e 0'.split()[ord(s[0])+ord(s[1])*2&7];s=s[3:]
print p,'ESWN'[d%4]

Exemplo:

% python2.7 ams.py <<<'o/,~~,~~,~-,::'
(-1+2j) E

Isso imprime números complexos, o que deve ser bom, eu acho? A x, y, hfim ainda está lá, e 'j'não causa qualquer confusão. Diga-me se devo mudar.

Lynn
fonte