Be My Navigator

8

Oh não, estou perdido no caminho de encontrar os grandes tesouros de Marakov! E tudo o que tenho são essas instruções inúteis que parecem S10R10D30... Não faço ideia do que elas significam! Pode me ajudar?

Desafio

Dadas as direções consistindo em N E S W U D L R 1 2 3 4 5 6 7 8 9 0, indica a que distância estarei de onde comecei quando sigo essas instruções (ou seja, Distância Euclidiana).

N E S W refira-me a virar para o norte, leste, sul e oeste;

U D L Rrefira-me a girar para cima, para baixo, para a esquerda e para a direita (assim NRé o mesmo que Ee assim é SL; SLLé o mesmo que N). Up significa seguir em frente; Para baixo significa virar.

Após cada direção da letra, haverá um número, que é o quão longe eu irei nessa direção. N10E20significa ir para o norte 10 unidades, depois virar para o leste e ir para o leste 20 unidades.

Detalhes da entrada

  • A entrada sempre começará com uma das NESWopções (portanto, as entradas em branco não precisam ser contabilizadas).
  • São permitidas instruções de duas letras seguidas. NEdeve ser interpretado: "Vire para o norte e depois imediatamente para o leste". É o mesmo que apenas E. SLLé "Vire para o sul e, imediatamente, vire à esquerda duas vezes". É o mesmo que N.
  • Todos os números serão inteiros (observe como .não está no conjunto de caracteres)
  • A entrada será composta apenas por NESWUDLR1234567890(se precisar de algo mais, como '\ 0' em C; ou se as funções de entrada do seu idioma tiverem uma nova linha à direita, ou algo assim, tudo bem.)

Resultado

  • A norma.
  • Se estiver usando uma função, deve gerar um tipo de dados numérico ou uma string.
  • Deve ter precisão de 3 casas decimais.

Casos de teste

  • N10: 10
  • N10E10: 14.1421
  • N10S10: 0
  • NSEWUDLR10: 10
  • N100RR20E300D40L12: 268.7452
  • ERR10LL20UN30D100: 70.71067

O programa Python sem imaginação que eu costumava fazer isso.

Ganhando

Isso é codegolf, então os bytes mais baixos depois de uma semana vencem!

Quelklef
fonte
@AdmBorkBork Right. Deixe-me editar.
Quelklef
Relacionado
AdmBorkBork
@AdmBorkBork Também isso , mas todos são um pouco diferentes.
Quelklef
Podemos assumir que a entrada consiste apenas em NESWUDLR1234567890?
darrylyeo
@ Darrylyeo Claro, deixe-me editar.
Quelklef

Respostas:

2

(Go) Ruby , 111 bytes

x=0
c=1,1i,-1,-1i
gs.sc(/(\w)(\d*)/){|o,a|x+=c.ro!('URDL'.ix(o)||'NESW'.ix(o)+c.ix(1)).fs*a.toi}
p Mh::hy *x.rc

Experimente online!

Recebe entrada em STDIN e em STDOUT.

Basicamente, essa abordagem usa números complexos para armazenar a posição atual, bem como uma pilha ( c), contendo deslocamentos para cada direção. Se houver uma direção URDL, a pilha é girada pelo índice da direção nessa sequência; se a direção estiver NESW, ela será girada pelo índice da direção nessa sequência, mais o índice da 1pilha. Isso transforma uma rotação relativa à posição atual em uma rotação relativa à posição de 1. De qualquer forma, a parte superior da pilha é multiplicada pelo número de etapas na direção e adicionada à posição atual.

Tutleman
fonte
O que é "(Go) Ruby"?
Carcigenicate
@Carcigenicate É Ruby, onde o intérprete foi compilado com uma bandeira especial que o torna mais adequado para jogar golfe. Entre outras alterações, ele permite abreviar nomes de métodos e altera o comportamento de certos recursos internos. Se você visitar o meu link TiO, verá o código no cabeçalho, que é a maioria das alterações feitas.
Tutleman
4

Python 3 , 137 bytes

v=n=0
d=1
for i in input()+'U':x="NUERSDW0123456789".find(i);c=x<7;v+=d*n*c;n=[n*10+x-7,0][c];d=[d,d**(x%2)*1j**(~-x/2)][c]
print(abs(v))

Experimente online!

-9 bytes graças a Jonathan Allan

HyperNeutrino
fonte
Você pode salvar seis bytes com a cláusula else: else:v+=d*n;n=0;h='NUERSDW'.find(i);d=d**(h%2)*1j**(~-h/2)- observe que Lpode ser cortado no final da cadeia de caracteres de busca aqui porque -1%2iguais 7%2e 1j**(-1)iguais 1j**3.
Jonathan Allan
@JonathanAllan Nice tricks! Obrigado!
HyperNeutrino
Salve outros três, adicionando o seguinte para:for i in input()+'U':x="NUERSDW0123456789".find(i);c=x<7;v+=d*n*c;n=[n*10+x-7,0][c];d=[d,d**(x%2)*1j**(~-x/2)][c]
Jonathan Allan
@JonathanAllan Ei legal, obrigado!
HyperNeutrino
Tentei minha própria mão em uma resposta Python, não consegui ficar abaixo de 179 bytes. Bravo.
Quelklef 03/08/19
2

JavaScript (ES6), 148 142 140 138 137 134 134 bytes

s=>s.replace(/\d+|./g,_=>~(i='NESW'.search(_))?d=i:~(i='URDL'.search(_))?d+=i:a[d&3]+=+_,a=[0,0,0,0])&&Math.hypot(a[1]-a[3],a[0]-a[2])

-2 bytes: use em .search()vez de .indexOf()( @Shaggy )

-1 byte: Reorganize o programa para remover os parênteses ( @Shaggy )

-3 bytes: use em .replace()vez de .match().map()( @ThePirateBay )

darrylyeo
fonte
Estamos recebendo respostas diferentes para o penúltimo teste.
Quelklef
@Quelklef Fixed.
darrylyeo
Você pode salvar alguns bytes usando em searchvez de indexOf?
Shaggy
Eu acho que você também pode salvar um byte, movendo a- se para o map, substituindo o ,anterior Mathpor &&e removendo os parênteses.
Shaggy
@ Shaggy Awesome, obrigado!
darrylyeo
0

Perl 5 , 149 + 1 (-p) = 150 bytes

while(s/(\D+)(\d+)//){$p=/N/?0:/E/?1:/S/?2:/W/?3:/L/?$p-1:/R/?$p+1:/D/?$p+2:$p for split//,$1;$m[$p%4]+=$2}$_=sqrt(($m[0]-$m[2])**2+($m[1]-$m[3])**2)

Experimente online!

Explicado:

# Each direction is assigned a number:
#
#     0     North
#     1     East
#     2     South
#     3     West
#
# Variables:
#     $p     present direction
#     @m     total movement in each direction
# Inside loop:
#     $1     a set of direction instructions
#     $2     distance

while(s/(\D+)(\d+)//)    # Remove and preserve the first direction set and distance
   for split//,$1        # Loop through individual letters to set new direction
      $p=/N/?0:          # North
         /E/?1:          # South
         /S/?2:          # East
         /W/?3:          # West
         /L/?$p-1:       # Turn left
         /R/?$p+1:       # Turn right
         /D/?$p+2:       # Turn around
         $p              # Do not change direction
   $m[$p%4]+=$2          # Add the directional movement to previous movements

   $_=sqrt(              # Calculate distance
       ($m[0]-$m[2])**2  # Net North/South movement
      +($m[1]-$m[3])**2  # Net East/West movement
      )
Xcali
fonte