Onde eu estou agora?


21

Onde eu estou agora?

Dada uma sequência d, contendo apenas as letras NSWE, determine as coordenadas que eu viajei (da esquerda para a direita, consumindo avidamente) e a coordenada final em que eu moro.

As regras para leitura de coordenadas da esquerda para a direita:

  • Se o próximo caractere for NouS :
    • Se o caractere após o Nou Sfor outro NouS :
      • Consuma apenas o primeiro Nou S.
      • Saída [0,1] paraN
      • Saída [0,-1]paraS
    • Se o caractere após o Nou Sé WouE :
      • Consuma o Nou Se o Wou E.
      • Saída [1,1]ou [-1,1]para NEe NW, respectivamente.
      • Saída [1,-1]ou [-1,-1]para SEe SW, respectivamente.
  • Se o personagem for Eou Wnão precedido por um SouN :
    • Consuma o Eou W.
    • Saída [1,0]para E.
    • Saída [-1,0]para W.

Exemplo Trabalhado

NSWE

[0,1]   (North      N)
[-1,-1] (South-west SW)
[1,0]   (East       E)
[0,0]   (N+SW+E = Didn't actually move)

Observe que isso pode estar em qualquer formato, eis outros exemplos de saída válida:

[[0,1],[-1,-1],[1,0],[0,0]]


[[[0,1],[-1,-1],[1,0]],[0,0]]


"0,1\n0,-1\n-1,0\n1,0\n0,0"

Etc ...


Mais exemplos

SWSENNESWNE

[-1,-1]
[1,-1]
[0,1]
[1,1]
[-1,-1]
[1,1]
[1,0]

NNEESESSWWNW

[0,1]
[1,1]
[1,0]
[1,-1]
[0,-1]
[-1,-1]
[-1,0]
[-1,1]
[0,0]

NENENEE

[1,1]
[1,1]
[1,1]
[1,0]
[4,3]

NEN

[1,1]
[0,1]
[1,2]

EEE

[1,0]
[1,0]
[1,0]
[3,0]

Regras

  • Você pode imprimir em qualquer formato conveniente que não viole brechas.
  • Você deve consumir avidamente, NWEnunca é N,W,E, é sempre NW,E.
    • Isso se aplica a: SW*, SE*, NW*, NE*.
    • Você está consumindo da esquerda para a direita, avidamente.
  • O é , o menor número de bytes vence.

"determinar as coordenadas pelas quais viajei" : não tenho certeza se realmente corresponde ao que é descrito posteriormente. É mais como "determinar os vetores de todos os meus movimentos" . Somente a saída final são coordenadas reais.
— Arnauld

1
Um caso de teste que caminha para mais [4, 3]ou menos tornaria um pouco mais fácil ver o que está acontecendo na saída do teste.
— 21418 Lynn

3
São números complexos formatados como 1, -1j, (-1+1j)etc um formato de saída válido?
— Lynn

2
Com base na ausência deste caso, tanto nas regras quanto nos exemplos dados, assumo que a string de entrada nunca terminará em 'N' ou 'S'?
— Kevin Cruijssen

1
Consumir avidamente é realmente diferente? Desde que NEé apenas N+Enão deveria, não importa?
— Assistente de trigo

Respostas:


7

Python 2 , 116 bytes

import re
a=[(int(s,35)%5-3,('N'in s)-('S'in s))for s in re.findall('[NS][EW]?|.',input())]
print a,map(sum,zip(*a))

Experimente online!

Com saída como [(3+4j), 1, -1j, …], 91 bytes

lambda x:[sum(1j**(ord(c)%8%5)for c in s)for s in[x]+re.findall('[NS][EW]?|.',x)]
import re

Experimente online!

Este lambda retorna uma lista de números inteiros gaussianos : o primeiro é a coordenada final e todos os outros são os passos necessários para chegar lá.


5

Anexo , 80 bytes

V#Sum##{Chop[1-ToBase[22260446188,3],2][Sum@Ords=>MatchAll[_,/"[NS][WE]|."]%11]}

Experimente online!

Esta é uma função anônima que recebe um argumento de string.

Explicação

A primeira tarefa é implementar a fase de análise desta pergunta. Achei mais curto usar um Regex simples para analisar a entrada ( _):

MatchAll[_,/"[NS][WE]|."]

Isso corresponde a todas as ocorrências da regex [NS][WE]|., como visto em muitas outras respostas. Isso produz avidamente as instruções solicitadas.

Agora, vamos aplicar uma função de hash a cada direção. Pegamos os pontos de código de cada direção e os somamos. Isso fornece o seguinte mapeamento:

Direction       Ord-sum
E               69
N               78
S               83
W               87
NE              147
SE              152
NW              165
SW              170

Vamos tentar mapear esses valores para um domínio menor; módulo é útil para isso, e podemos demonstrar que o menor módulo que resulta em valores únicos para todas as entradas fornecidas é 11. Classificando pelos restantes, isso nos dá a seguinte tabela:

Direction       Ord-sum         % 11
NW              165             0
N               78              1
E               69              3
NE              147             4
SW              170             5
S               83              6
SE              152             9
W               87              10

Agora, temos uma correspondência de entrada, conforme codificada por Sum@Ords=>[...]%11. Em seguida, temos que transformar esses restos em pontos. Vamos tentar derivar outro mapeamento, o que significa que a inserção de "valores de preenchimento esparso" em hashes que não correspondem a direções deve ser útil:

Direction       Hash        Coordinates
NW              0           [-1, 1]
N               1           [0, 1]
--             (2)          [0, 0]
E               3           [1, 0]
NE              4           [1, 1]
SW              5           [-1, -1]
S               6           [0, -1]
--             (7)          [0, 0]
--             (8)          [0, 0]
SE              9           [1, -1]
W               10          [-1, 0]

Atualmente, temos uma série de pontos, o que pode fornecer uma lista indexável pelo hash:

[-1, 1] [0, 1] [0, 0] [1, 0] [1, 1] [-1, -1] [0, -1] [0, 0] [0, 0] [1, -1] [-1, 0]

Agora, vamos comprimir isto, vendo como seu único composto por -1s, 0s e 1s. Como a lista representa pares, podemos achatar a lista sem perder dados. Então, se pegarmos cada número xe calcularmos 1-x, obteremos a seguinte lista:

2 0 1 0 1 1 0 1 0 0 2 2 1 2 1 1 1 1 0 2 2 1

Podemos converter isso em um número base 3:

20101101002212111102213

Convertendo para a base 10:

20101101002212111102213 ≡ 2226044618810

Para resumir, pegamos nossos pontos, desemparelhamos eles, pegamos cada elemento subtraído 1e convertido da base 3, fornecendo-nos 22260446188. Podemos descomprimir como tal:

  1. Converter na base 3: ToBase[22260446188,3]
  2. Tome cada número subtraído de um (auto-inverso): 1-ToBase[22260446188,3]
  3. Emparelhe a lista novamente: Chop[1-ToBase[22260446188,3],2]

Isso nos dá o nosso conjunto original de pares. Em seguida, podemos executar a indexação acima mencionada da seguinte maneira:

(chopped value)[hashes]

Como no Attache, a indexação por uma matriz retorna todos os elementos correspondentes a esses índices. (Então [1,2,3,4][ [0,0,-1,1] ] = [1,1,4,2],.) Agora, temos as direções do caminho que o OP percorreu. O que resta é calcular a soma.

Então, capturamos esse resultado em um lambda {...}e o colocamos como a primeira função em uma composição de função ( a##b), com o segundo sendo V#Sum. Esta é uma bifurcação que, dada a entrada x, se expande para ser:

V[x, Sum[x]]

Sum, quando recebe uma matriz 2D, soma todas as colunas da matriz (como resultado da soma vetorial). Então, isso emparelha as direções com o destino final e temos nosso resultado final.


4

JavaScript (ES6), 102 bytes

Retorna uma string.

s=>s.replace(/[NS][EW]|./g,s=>(D=d=>!!s.match(d),x+=h=D`E`-D`W`,y+=v=D`N`-D`S`,[h,v]+`
`),x=y=0)+[x,y]

Experimente online!


Eu gosto do uso de funções de modelo! : D
— Conor O'Brien

@ ConorO'Brien Sim, eles são bastante úteis aqui. Todos os feitiços de feitiçaria que eu invoquei até agora são pelo menos um pouco mais longos.
— Arnauld

4

MATL , 45 bytes

'NS' 'WE'Z*Z{2MhX{h'eklihfmj'X{YX9\3_2&YAqts

Experimente online! Ou verifique todos os casos de teste .

Explicação (com exemplo)

Considere a entrada 'NSWE'como um exemplo.

'NS' 'WE'  % Push these two strings
           % STACK: 'NS', 'WE'
Z*         % Cartesian product. Gives a 4×2 char matrix
           % STACK: ['NW'; 'NE'; 'SW'; 'SE']
Z{         % Cell array of rows (strings)
           % STACK: {'NW', 'NE', 'SW', 'SE'}
2M         % Push again the inputs of the second-last function call
           % STACK: {'NW', 'NE', 'SW', 'SE'}, 'NS', 'WE'
h          % Concatenate horizontally
           % STACK: {'NW', 'NE', 'SW', 'SE'}, 'NSWE'
X{         % Cell array of individual elements (chars)
           % STACK: {'NW', 'NE', 'SW', 'SE'}, {'N', 'S', 'W', 'E'}
h          % Concatenate horizontally
           % STACK: {'NW', 'NE', 'SW', 'SE', 'N', 'S', 'W', 'E'}
'eklihfmj' % Push this string
           % STACK: {'NW', 'NE', 'SW', 'SE', 'N', 'S', 'W', 'E'}, 'eklihfmj'
X{         % Cell array of individual elements (chars)
           % STACK: {'NW','NE','SW','SE','N','S','W','E'},{'e','k','l','i','h','f','m','j'}
YX         % Implicit input. Regexp replace: replaces 'NW' by 'e', then 'NE' by 'k', etc.
           % Note that the two-letter combinations are replaced first, which implements
           % the greediness; and the target letters do not appear in the source, which
           % avoids unwanted interactions between replacements
           % STACK: 'hlj'
9\         % Modulo 9 (of codepoints), element-wise
           % STACK: [5, 0, 7]
3_2&YA     % Convert to base 3 with 2 digits. Gives a 2-column matrix
           % STACK: [1, 2; 0, 0; 2, 1]
q          % Subtract 1, element-wise
           % STACK: [0, -1; -1, -1; 1, 0]
tXs        % Duplicate. Sum of each column
           % STACK: [0, -1; -1, -1; 1, 0], [0, 0]
           % Implicit display

4

Java (JDK 10) , 171 bytes

s->{var r="";int i=0,l=s.length,c,x=0,y=0,Y,X;for(;i<l;X=c>1||i<l&&(c=~-s[i]/6%4)>1&&++i>0?c*2-5:0,r+=X+","+Y+" ",x+=X,y+=Y)Y=(c=~-s[i++]/6%4)<2?1-c*2:0;return r+x+","+y;}

Experimente online!

Explicações

Graças a c=~-s[i]/6%4, o seguinte mapeamento é feito:

'N' -> ascii: 78 -> -1 = 77 -> /6 = 12 -> %4 = 0
'S' -> ascii: 83 -> -1 = 83 -> /6 = 13 -> %4 = 1
'W' -> ascii: 87 -> -1 = 86 -> /6 = 14 -> %4 = 2
'E' -> ascii: 69 -> -1 = 68 -> /6 = 11 -> %4 = 3
  • NSé verificado c<2e mapeado para +1/ -1usando 1-c*2;
  • EWé verificado c>1e mapeado para +1/ -1usando c*2-5.

Créditos


Ah, você postou sua resposta Java enquanto eu estava digitando a explicação minha. :) Como nós dois usamos uma abordagem completamente diferente, deixarei a minha por enquanto. Variáveis ​​muito ruins usadas em lambdas precisam ser efetivamente finais, caso contrário, você poderia ter retornado uma String em vez de uma List para salvar bytes.
— Kevin Cruijssen

Graças, ela só salvou alguns bytes (4), mas é melhor do que nada;)
— Olivier Grégoire

@KevinCruijssen Obrigado, parecia bastante óbvio no começo, mas eu estava trabalhando em outra abordagem que reduziu minha contagem de bytes em mais de 30. Uma "análise", uma não "correspondente".
— Olivier Grégoire


1
@KevinCruijssen Desculpe, está uma bagunça na integração de suas alterações ... Estou no trabalho e esqueci de atualizar esta página ... Obrigado por tudo de qualquer maneira ^^ 'A contagem de créditos está muito abaixo do seu crédito real. Também desculpe por isso: s #
— Olivier Grégoire

3

Retina 0.8.2 , 93 bytes

.+
$&¶$&
\G[NS]?[EW]?
$&¶
G`.
W
J
%O`.
+`EJ|NS

m`^((J)?[EJ]*)((S)?[NS]*)
$#2$*-$.1,$#4$*-$.3

Experimente online! Explicação:

.+
$&¶$&

Duplique a entrada.

\G[NS]?[EW]?
$&¶

Divida a primeira cópia em direções.

G`.

Remova linhas em branco estranhas criadas pelo processo acima.

W
J

Mude Wpara Jpara classificar entre Ee N. (Passar Epara o meio Se Wtambém funcionaria.)

%O`.

Classifique cada linha em ordem.

+`EJ|NS

Exclua pares de direções opostas (isso afeta apenas a última linha, é claro).

m`^((J)?[EJ]*)((S)?[NS]*)
$#2$*-$.1,$#4$*-$.3

Conte o número de movimentos horizontais e verticais, adicionando sinais sempre que necessário.

Aqueles de vocês que conhecem as diferenças entre o Retina 0.8.2 e o Retina 1 querem salientar que eu posso salvar 2 bytes no Retina 1 porque ele usa em *vez de $*. Enquanto estava lá, tentei simplificar o processo de divisão, mas não consegui reduzir ainda mais a contagem de bytes, só consegui igualá-la a isto:

L$`$(?<=(.*))|[NS]?[EW]?
$&$1

3

Java 10, 269 265 243 bytes

s->{var r="";int x=0,y=0,t,X,Y,a;for(;!s.isEmpty();r+=X+"|"+Y+" ",s=s.substring(++t),x+=X,y+=Y){a=s.charAt(t=0);if(s.matches("[SN][WE].*")){X=s.charAt(1)<70?1:-1;Y=1-a%2*2;t++;}else{X=a<70?1:a>86?-1:0;Y=a>69&a<87?1-a%2*2:0;}}return r+x+"|"+y;}

Definitivamente, não é o idioma certo para este desafio.

Experimente online.

Explicação:

s->{                  // Method with String as both parameter and return-type
  var r="";           //  Result-String, starting empty
  int x=0,            //  Ending `x`-coordinate, starting at 0
      y=0,            //  Ending `y`-coordinate, starting at 0
      t,X,Y,a;        //  Temp-integers
  for(;!s.isEmpty()   //  Loop as long as the input-String is not empty yet
      ;               //    After every iteration:
       r+=X+"|"+Y+" ",//     Append the current steps to the result-String
       s=s.substring(t),
                      //     Remove the first `t` characters from the input-String
       x+=X,y+=Y){   //      Append the ending `x`,`y` coordinates with the steps
    a=s.charAt(0);   //    Set `a` to the first character of the input-String to save bytes
    t=1;             //    Set `t` to 1
    if(s.matches("[SN][WE].*")){
                     //   Else-if the input-String starts with N/S followed by E/W:
      X=s.charAt(1)<70?1:-1;
                     //    Set `X` to 1 if 'E', -1 if 'W'
      Y=1-a%2*2;     //    Set `Y` to 1 if 'N', -1 if 'S'
      t++;}          //    Increase `t` by 1
    else{            //   Else:
      X=a<70?1:a>86?-1:0;
                     //    Set `X` to 1 if 'E', -1 if 'W', 0 if 'N' or 'S'
      Y=a>69&a<87?1-a%2*2:0;}}
                     //    Set `Y` 1 if 'N', -1 if 'S', 0 if 'E' or 'W'
  return r+x+"|"+y;} //  Append the ending coordinates, and return the result-String

1
As respostas Java obtêm pontos, porque todos os recebem :).
— Urna de polvo mágico

@MagicOctopusUrn True. :) E ainda gosto de jogar golfe em Java, mesmo que você nunca seja o menor. A menos que seja o único a responder (tenho duas respostas Java aceitas .. XD). No entanto, para este desafio, a resposta Java de OlivierGrégoire é cerca de 70 bytes mais curta; portanto, a maioria dos votos positivos deve ser enviada a ele.
— Kevin Cruijssen


2

JavaScript (ES6), 102 bytes

f=
s=>s.replace(/((N)|(S))?((E)|(W))?/g,(m,v,n,s,h,e,w)=>(x+=h=!w-!e,y+=v=!s-!n,m?[h,v]+`
`:[x,y]),x=y=0)
<input oninput=o.textContent=/[^NSEW]/.test(this.value)?``:f(this.value)><pre id=o>0,0

Retorna uma string.


1

Ruby , 75 71 bytes

->x{[*x.scan(/[NS][EW]?|./),x].map{|s|s.chars.sum{|c|1i**(c.ord%8%5)}}}

Experimente online!

-4 bytes graças a benj2240.

Como retornar números complexos parece ser um formato de saída aceitável, acho que não ficará muito mais difícil do que apenas fazer uma porta da resposta muito agradável de Lynn .


Muito agradável. você pode salvar alguns bytes pulando o interior map, passando seu bloco diretamente para sum: Experimente online!
— precisa saber é o seguinte

1

F # (Mono) , 269 bytes

let f s=
 let l,h=(string s).Replace("NW","A").Replace("NE","B").Replace("SW","C").Replace("SE","D")|>Seq.map(function 'N'->0,1|'S'->0,-1|'W'-> -1,0|'E'->1,0|'A'-> -1,1|'B'->1,1|'C'-> -1,-1|'D'->1,-1)|>Seq.mapFold(fun(x,y) (s,t)->(s,t),(x+s,y+t))(0,0)
 Seq.append l [h]

Experimente online!


Olá, seja bem-vindo ao PPCG. Infelizmente, você está perdendo o último item da sua saída, que deve ser a posição em que você terminou. Assim, para o NSWEque está actualmente a saída (0,1), (-1,-1), (1,0), mas uma quarta saída deve ser a soma dessas coordenadas, então (0,0)(porque 0+-1+1 = 0e 1+-1+0 = 0).
— Kevin Cruijssen

@KevinCruijssen OK, eu não entendi. Fiz uma atualização.
— Henrik Hansen

1
Parece funcionar muito bem agora, então +1 de mim. Aproveite sua estadia! :) E caso você ainda não tenha visto, Dicas para jogar golfe em F # e Dicas para jogar golfe em <todos os idiomas> podem ser interessantes para ler.
— Kevin Cruijssen

1

sed, 125

As liberdades de obtenção com a versão do formato de saída :

A pontuação inclui +1 para o -rparâmetro sed.

s/(N|S)(E|W)/\L\2,\1 /g
s/N|S/,& /g
s/E|W/&, /g
s/N|E/A/gi
s/S|W/a/gi
p
:
s/(\S*),(\S*) (\S*),(\S*)/\1\3,\2\4/
t
s/Aa|aA//
t

Experimente online .

A saída é a seguinte:

  • elementos de coordenadas são separados por vírgula
  • cada conjunto de coordenadas é separado por TAB
  • a coordenada final está em uma nova linha
  • todos os números estão em ℤ-unário:
    • uma sequência de Acaracteres representa o número inteiro + velen(string)
    • uma sequência de acaracteres representa o inteiro -ve-len(string)
    • a cadeia vazia representa 0

Por exemplo:

  • , é [0,0]
  • ,AA é [0,2]
  • aaa, é [-3,0]

sed 4.2.2 incluindo extensão exec GNU , 147

A versão do formato de saída sensível :

A pontuação inclui +1 para o -rparâmetro sed.

s/(N|S)(E|W)/\L\2 \1\n/g
s/N|S/0 &\n/g
s/E|W/& 0\n/g
s/N|E/1/gi
s/S|W/-1/gi
p
:
s/(\S+) (\S+)\n(\S+) (\S+)/\1+\3 \2+\4/
t
s/\S+/$[&]/g
s/^/echo /e

A saída é fornecida como coordenadas separadas por espaço, uma por linha. Há uma nova linha extra entre os penúltimos e últimos conjuntos de coordenadas - não tenho certeza se isso é problemático ou não.

Experimente online!


0

PHP, 153 bytes

deixe um regex fazer a divisão; percorrer as correspondências, imprimir e resumir os resultados intermediários:

preg_match_all("/[NS][EW]?|E|W/",$argn,$m);foreach($m[0]as$s){$x+=$p=strtr($s[-1],NEWS,1201)-1;$y+=$q=strtr($s[0],NEWS,2110)-1;echo"$p,$q
";}echo"$x,$y";

Execute como pipe -nRou experimente online .


0

C (gcc) , 173 bytes

É interessante fazer isso em um idioma sem suporte a regex!

f(char*s){char*t="[%d,%d]\n";int x[4]={0},i;for(;*s;*x=x[1]=!printf(t,x[1],*x))for(i=-1;i<5;)if(*s=="S NW E"[++i]){x[i/3+2]+=x[i/3]=i%3-1;i+=2-i%3;s++;}printf(t,x[3],x[2]);}

Experimente online!


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.