Secuencia de distancia de rotación de Manhattan

9

Pensé que este sería un buen desafío: http://adventofcode.com/2016/day/1

Descripción de la tarea

Dada una secuencia de rotaciones y distancias que siguen el patrón (L | R) [1-9] [0-9] *, proporcione la distancia de Manhattan entre los puntos inicial y final, que es el número mínimo de movimientos verticales y horizontales en una cuadrícula

Ejemplos

Por ejemplo, si suponemos que comenzó a mirar hacia el norte:

Después de R2, L3 te deja 2 cuadras al este y 3 cuadras al norte, o 5 cuadras de distancia. R2, R2, R2 te deja a 2 cuadras al sur de tu posición inicial, que está a 2 cuadras de distancia. R5, L5, R5, R3 te deja a 12 cuadras de distancia.

Detalles técnicos

Puede elegir el separador entre los movimientos (por ejemplo: "\ n", "," o ","). Debe dar la respuesta como un entero en la base 10.

No es un duplicado!

No es un duplicado por múltiples razones:

  • Los movimientos no son lo mismo. Aquí hay rotaciones , no direcciones.
  • Quiero la distancia de Manhattan, no la euclidiana.
Labo
fuente
3
Debe incluir una descripción de la distancia de Manhattan en su pregunta. Solo publicar un enlace es algo hortera.
Gabriel Benamy
2
Es muy diferente ! ¡Solo tenemos rotaciones!
Labo
1
@Labo estoy de acuerdo. No se trata solo del hecho de que la respuesta aquí está en la distancia de Manhattan, mientras que la otra está en la distancia euclidiana. Esto tiene movimiento de estilo tortuga mientras que el otro especifica las direcciones de la brújula NSEW (el hecho de que los llama UDLR es irrelevante).
Level River St
2
Utilice Sandbox en el futuro para obtener comentarios sobre sus desafíos antes de publicarlos en el sitio principal.
Mego
2
@Labo Está bien, no esperamos que los nuevos usuarios conozcan todos los entresijos de este sitio de inmediato. Es solo una suave sugerencia para la próxima vez. :)
Mego

Respuestas:

4

Python 3, 109 99 104 101 bytes

Esta es una respuesta simple que usa números complejos, con entrada como una cadena separada por espacios o una cadena separada por una nueva línea. Sugerencias de golf bienvenidas!

Editar: -13 bytes gracias a Labo. +5 bytes para convertir a un int.

d=p=0
for r in input().split():d+=1-2*(r<'R');p+=1j**d*int(r[1:])
print(int(abs(p.real)+abs(p.imag)))

Ungolfing

def manhattan_rotation(seq, nsew=0, pos = 0):
    for rot in seq.split():
        # change direction
        if rot[0] == "L":
            nsew += -1 
        else:
            nsew += 1
        # move in that direction rot[1:] times
        pos += 1j ** nsew * int(rot[1:])
    return int(abs(pos.real)+abs(pos.imag))
Sherlock9
fuente
1-2 * (r [0] <'R') le ahorrará 2 bytes :)
Labo
¡No hagas una función, leer de la entrada te hace guardar más caracteres!
Labo
Asigne 2 variables en la misma línea para guardar 2 bytes: d = p = 0
Labo
¡Volví a jugar tu respuesta y hace 99 caracteres! pastie.org/private/hm7lejqosdqnkgo000u7q
Labo
2
@Labo No estoy seguro de que pueda editar la especificación de una manera que invalidaría las respuestas existentes, pero permítame preguntarle algunas modificaciones.
Sherlock9
2

PHP, 93 bytes

while($m=$argv[++$i])${chr(80|3&$d+=(P<$m)-(M>$m))}+=substr($m,1);echo abs($P-$R)+abs($Q-$S);

Descompostura

while($m=$argv[++$i])       // loop through arguments:
    ${                      // 5. use as variable name
        chr(                // 4. cast to character (P,Q,R,S) 
        80|                 // 3. add 80
        3&                  // 2. modulo 4
        $d+=(P<$m)-(M>$m)   // 1. change direction depending on letter
    )}+=substr($m,1);       // 6. add number to variable
echo abs($P-$R)+abs($Q-$S); // calculate distance, print
Tito
fuente
2

Python 2, 86 bytes

x=y=0
for d in input().split():c=cmp(d,'M');x,y=int(d[1:])-y*c,x*c
print abs(x)+abs(y)

Rastrea la corriente xy las ycoordenadas. Al girar, en lugar de actualizar la dirección, gira el valor actual para que el movimiento siempre esté en la dirección x positiva. Los números complejos eran demasiado costosos para extraer las coordenadas.

xnor
fuente
1

Python 2, 103102 bytes

l=c=0
for i in input().split():c+=cmp(i[0],'N');l+=1j**c*int(i[1:])
print int(abs(l.imag)+abs(l.real))

repl.it

La entrada es una cadena de direcciones delimitadas por espacios, por ejemplo "R5 L5 R5 R3".
Imprime la distancia de Manhattan entre la ubicación inicial y el destino.

¿Cómo?

Comienza en el origen del plano complejo l=0;

Con un contador de giro de cuarto a la derecha acumulativo c=0;

Para cada instrucción, ila rotación se analiza comparando el primer carácter de la dirección con el carácter 'N', y cse ajusta en consecuencia.

La distancia a recorrer se analiza int(i[1:])y la instrucción se promulga dando tantos pasos del tamaño de un bloque en la dirección dada tomando la cpotencia de 0+1jcon 1j**c.

La distancia final de Manhattan es la suma de las distancias absolutas desde el origen en las dos direcciones: imaginaria y real; logrado conabs(l.imag)+abs(l.real)

Jonathan Allan
fuente
1
@ Sherlock9 - Oh, um respuesta convergencia. Ahorre 2 bytes cambiando a Python 2 y utilizando cmpcomo mi respuesta, avíseme y lo eliminaré.
Jonathan Allan
0

JavaScript (ES2016), 98 100

2 bytes guardados gracias a @Neil

d=>d.replace(/.(\d+)/g,(d,l)=>(o+=d>'M'||3,l*=~-(o&2),o&1?x-=l:y+=l),x=y=o=0)&&(x*x)**.5+(y*y)**.5

100 bytes para ES6

d=>d.replace(/.(\d+)/g,(d,l)=>(o+=d>'M'||3,l*=~-(o&2),o&1?x-=l:y+=l),x=y=o=0)&&(x>0?x:-x)+(y>0?y:-y)

Menos golf

d => d.replace(/.(\d+)/g,
  (d,l)=>( // L or R in d, distance in l
    o += d>'M' || 3, // orientation in o, used %4
    l *= ~-(o&2), // convert to number and change sign if needed
    o&1 ? x -= l : y += l // move based on orientation
  ), x = y = o = 0)
&& (x>0?x:-x) + (y>0?y:-y)

Prueba (ES6)

F=
d=>d.replace(/.(\d+)/g,(d,l)=>(o+=d>'M'||3,l*=~-(o&2),o&1?x-=l:y+=l),x=y=o=0)&&(x>0?x:-x)+(y>0?y:-y)

function update() {
  O.textContent=F(I.value)
}

update()
<input id=I value='R5, L5, R5, R3' oninput='update()'><pre id=O></pre>

edc65
fuente
1
Mi respuesta ES6 fue originalmente 106 bytes; copiar su variable intermedia me ahorró 3 bytes; cambiar de coincidencia a su reemplazo me ahorró 2 bytes, y copiar su procesamiento de la dirección y la distancia al mismo tiempo me ahorró un byte final, lo que resultó en esto: s=>s.replace(/.(\d+)/g,(c,n)=>(d+=c<'R'||3,n*=~-(d&2),d&1?x+=n:y+=n),x=y=d=0)&&(x<0?-x:x)+(y<0?-y:y)que ahora es dos bytes más corto que su respuesta ES6, gracias a los trucos c<'R'||3y n*=~-(d&2).
Neil