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.