¿Dónde estoy ahora?

21

¿Dónde estoy ahora?

Dada una cadena d, que contiene solo las letras NSWE, determina las coordenadas que he viajado (de izquierda a derecha, consumiendo con avidez) y la coordenada final donde resido.

Las reglas para leer las coordenadas de izquierda a derecha:

  • Si el siguiente personaje es NoS :
    • Si el personaje después de No Ses otro NoS :
      • Consume solo el primero No S.
      • Salida [0,1] paraN
      • Salida [0,-1]paraS
    • Si el personaje después de No Ses WoE :
      • Consume tanto el No Scomo el Wo E.
      • Salida [1,1]o [-1,1]para NEy NW, respectivamente.
      • Salida [1,-1]o [-1,-1]para SEy SW, respectivamente.
  • Si el personaje está precedido Eo Wno por un SoN :
    • Consume la Eo W.
    • Salida [1,0]para E.
    • Salida [-1,0]para W.

Ejemplo trabajado

NSWE

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

Tenga en cuenta que esto puede estar en cualquier formato, aquí hay otros ejemplos de resultados válidos:

[[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 ...


Más ejemplos

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]

Reglas

  • Puede imprimir en cualquier formato conveniente que no viole las lagunas.
  • Debes consumir con avidez, NWEes nunca N,W,E, es siempre NW,E.
    • Esto se aplica a: SW*, SE*, NW*, NE*.
    • Estás consumiendo de izquierda a derecha, con avidez.
  • El es el , el menor recuento de bytes gana.
Urna de pulpo mágico
fuente
"determinar las coordenadas que he viajado" : no estoy seguro de si realmente coincide con lo que se describe más adelante. Es más como "determinar los vectores de todos mis movimientos" . Solo el resultado final son las coordenadas reales.
Arnauld
1
Un caso de prueba que se acerque más [4, 3]o menos hará que sea un poco más fácil ver lo que está sucediendo en la salida de prueba.
Lynn
3
Se formatean los números complejos como 1, -1j, (-1+1j)formato de salida válida etc una?
Lynn
2
Basado en la ausencia de este caso tanto en las reglas como en los ejemplos dados, supongo que la cadena de entrada nunca terminará en una 'N' o 'S'.
Kevin Cruijssen
1
¿Consumir con avidez es realmente diferente de lo que no? Ya que NEes simplemente N+Eno debería importar?
Wheat Wizard

Respuestas:

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))

Pruébalo en línea!

Con salida 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

Pruébalo en línea!

Esta lambda devuelve una lista de enteros gaussianos : el primero es la coordenada final, y todos los demás son los pasos necesarios para llegar allí.

Lynn
fuente
5

Adjunto , 80 bytes

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

Pruébalo en línea!

Esta es una función anónima que toma un argumento de cadena.

Explicación

La primera tarea es implementar la fase de análisis de esta pregunta. Encontré que era más corto usar una expresión regular simple para analizar la entrada ( _)

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

Esto coincide con todas las ocurrencias de la expresión regular [NS][WE]|., como se ve en muchas otras respuestas. Esto produce avariciosamente las instrucciones solicitadas.

Ahora, vamos a aplicar una función hash a cada dirección. Tomamos los puntos de código de cada dirección y los sumamos. Esto proporciona la siguiente asignación:

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

Intentaremos asignar estos valores a un dominio más pequeño; el módulo es útil para esto, y podemos demostrar que el módulo más pequeño que da como resultado valores únicos para todas las entradas dadas es 11. Ordenando por restos, esto nos da la siguiente tabla:

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

Ahora, tenemos una correspondencia de entrada, como codificación por Sum@Ords=>[...]%11. Luego, tenemos que transformar estos residuos en puntos. Intentaremos derivar otro mapeo, lo que significa que será útil insertar "valores de relleno disperso" en hashes que no corresponden a las direcciones:

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]

Actualmente tenemos una serie de puntos, que pueden dar una lista indexable por el hash:

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

Ahora, comprimiremos esto, ya que solo se compone de -1s, 0sy 1s. Como la lista representa pares, podemos aplanar la lista sin perder datos. Luego, si tomamos cada número xy calculamos 1-x, obtenemos la siguiente lista:

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

Podemos convertir esto en un número base 3:

20101101002212111102213

Convirtiendo a base 10:

20101101002212111102213 ≡ 2226044618810

Para resumir, tomamos nuestros puntos, los desemparejamos, tomamos cada elemento restado de 1, y convertimos de base 3, dándonos 22260446188. Podemos descomprimir como tal:

  1. Convertir a base 3: ToBase[22260446188,3]
  2. Tome cada número restado de uno (autoinverso): 1-ToBase[22260446188,3]
  3. Vuelva a emparejar la lista: Chop[1-ToBase[22260446188,3],2]

Esto nos da nuestro conjunto original de pares. Entonces, podemos realizar la indexación antes mencionada de esta manera:

(chopped value)[hashes]

Dado que, en Attache, la indexación por una matriz devuelve todos los elementos correspondientes a esos índices. (Entonces [1,2,3,4][ [0,0,-1,1] ] = [1,1,4,2],.) Ahora, tenemos las direcciones de la ruta que recorrió el OP. Lo que queda es calcular la suma.

Entonces capturamos este resultado en un lambda {...}y lo ponemos como la primera función en una composición de función ( a##b), con el segundo ser V#Sum. Esta es una bifurcación que, dada la entrada x, se expande para ser:

V[x, Sum[x]]

Sum, cuando se le da una matriz 2D, se suman todas las columnas de la matriz (como resultado de la suma vectorializada). Entonces, esto empareja las direcciones con el destino final, y tenemos nuestro resultado final.

Conor O'Brien
fuente
4

JavaScript (ES6), 102 bytes

Devuelve una cadena.

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]

Pruébalo en línea!

Arnauld
fuente
¡Me gusta el uso de funciones de plantilla! : D
Conor O'Brien
@ ConorO'Brien Sí, son bastante útiles aquí. Todos los hechizos de hechicería hash que he convocado hasta ahora son al menos un poco más largos.
Arnauld
4

MATL , 45 bytes

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

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación (con ejemplo)

Considere la entrada 'NSWE'como un ejemplo.

'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
Luis Mendo
fuente
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;}

Pruébalo en línea!

Explicaciones

Gracias a c=~-s[i]/6%4, se realiza el siguiente mapeo:

'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
  • NSse verifica con c<2y se asigna a +1/ -1using 1-c*2;
  • EWse verifica con c>1y se asigna a +1/ -1utilizando c*2-5.

Créditos

Olivier Grégoire
fuente
Ah, publicaste tu respuesta Java mientras escribía la explicación mía. :) Como ambos usamos un enfoque completamente diferente, dejaré el mío por ahora. Las variables demasiado malas utilizadas en lambdas deben ser efectivamente finales, de lo contrario, podría haber devuelto una Cadena en lugar de una Lista para guardar bytes.
Kevin Cruijssen
Gracias, solo salvó unos pocos bytes (4), pero es mejor que nada;)
Olivier Grégoire
@KevinCruijssen Gracias, al principio parecía bastante obvio, pero estaba trabajando en otro enfoque que redujo mi recuento de bytes en más de 30. Un "análisis", no uno "coincidente".
Olivier Grégoire
1
Suspiro .. 172 bytes
Kevin Cruijssen
1
@KevinCruijssen Lo siento, es un desastre integrar sus cambios ... Me llevan al trabajo y me olvido de actualizar esta página ... Gracias de todos modos ^^ 'Es muy probable que el recuento de crédito esté por debajo de su crédito real. Lo siento también por eso: 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

Pruébalo en línea! Explicación:

.+
$&¶$&

Duplicar la entrada.

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

Divide la primera copia en direcciones.

G`.

Elimine las líneas en blanco extrañas creadas por el proceso anterior.

W
J

Cambie Wa Jpara que se clasifique entre Ey N. (Pasar Ea entre Sy Wtambién funcionaría).

%O`.

Ordenar cada línea en orden.

+`EJ|NS

Eliminar pares de direcciones opuestas (esto solo afecta a la última línea de curso).

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

Cuente la cantidad de movimientos horizontales y verticales, agregando signos cuando sea necesario.

Aquellos de ustedes que conocen las diferencias entre Retina 0.8.2 y Retina 1 querrán señalar que puedo guardar 2 bytes en Retina 1 porque usa en *lugar de $*. Mientras estuve allí, intenté simplificar el proceso de división, pero no pude reducir aún más el conteo de bytes, solo pude igualarlo con esto:

L$`$(?<=(.*))|[NS]?[EW]?
$&$1
Neil
fuente
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 no es el lenguaje correcto para este desafío.

Pruébalo en línea.

Explicación:

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
Kevin Cruijssen
fuente
1
Las respuestas de Java obtienen puntos porque todos las obtienen :).
Urna de pulpo mágico
@MagicOctopusUrn Verdadero. :) Y todavía disfruto jugando al golf en Java, a pesar de que nunca serás el más bajo ... A menos que seas el único en responder (obtuve dos respuestas aceptadas de Java ... XD). Sin embargo, para este desafío, la respuesta de Java de OlivierGrégoire es aproximadamente 70 bytes más corta, por lo que la mayoría de los votos a favor deberían ir a él.
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

Devuelve una cadena.

Neil
fuente
1

Ruby , 75 71 bytes

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

Pruébalo en línea!

-4 bytes gracias a benj2240.

Dado que devolver números complejos parece ser un formato de salida aceptable, supongo que no se volverá mucho más golfista que simplemente hacer un puerto de la muy buena respuesta de Lynn .

Kirill L.
fuente
Muy agradable. puede guardar algunos bytes omitiendo el interno map, pasando su bloque directamente a sum: ¡ Pruébelo en línea!
benj2240
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]

Pruébalo en línea!

Henrik Hansen
fuente
Hola, bienvenido a PPCG. Desafortunadamente, te estás perdiendo el último elemento de tu salida, que debería ser la posición donde terminaste. Así que para el NSWEque está dando salida actualmente (0,1), (-1,-1), (1,0), pero una cuarta salida debe ser la suma de esas coordenadas, por lo que (0,0)(debido 0+-1+1 = 0y 1+-1+0 = 0).
Kevin Cruijssen
@KevinCruijssen OK, no entendí eso. Hizo una actualización.
Henrik Hansen
1
Parece que funciona muy bien ahora, así que +1 de mi parte. ¡Disfruta tu estancia! :) Y en caso de que aún no lo hayas visto, los consejos para jugar golf en F # y los consejos para jugar golf en <todos los idiomas> pueden ser interesantes de leer.
Kevin Cruijssen
1

sed, 125

Las libertades con la versión en formato de salida :

La puntuación incluye +1 para el -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

Pruébalo en línea .

La salida es la siguiente:

  • los elementos de coordenadas están separados por comas
  • cada conjunto de coordenadas están separadas por TAB
  • la coordenada final está en una nueva línea
  • todos los números están en ℤ-unario:
    • una cadena de Acaracteres representa el entero + velen(string)
    • una cadena de acaracteres representa el entero -ve-len(string)
    • la cadena vacía representa 0

Por ejemplo:

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

sed 4.2.2 incluyendo la extensión exec de GNU , 147

El formato de salida sensible versión del :

La puntuación incluye +1 para el -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

La salida se da como coordenadas separadas por espacios, una por línea. Hay una nueva línea adicional entre el penúltimo y último conjunto de coordenadas, no estoy seguro de si eso es problemático o no.

Pruébalo en línea!

Trauma digital
fuente
0

PHP, 153 bytes

deja que una expresión regular haga la división; recorrer los partidos, imprimir y resumir los resultados intermedios:

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";

Ejecutar como tubería -nRo probarlo en línea .

Tito
fuente
0

C (gcc) , 173 bytes

¡Es interesante hacer esto en un idioma sin soporte de expresiones regulares!

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]);}

Pruébalo en línea!

ErikF
fuente
164 bytes
ceilingcat