Vectores euclidianos

14

Dado el arte ASCII de dos vectores, encuentre la magnitud y el grado del vector resultante.


Entrada

Esto puede recibirse a través de STDIN, leerse desde un archivo local o proporcionarse a través de una llamada de función. Aquí hay un ejemplo de una entrada de dos vectores:

^------>
|
|
|
x

Esto representa un cambio de 4 unidades al norte y 7 unidades al este. El punto de partida de cada entrada estará representado por unx (decimal 120).

  • Todos los vectores son líneas horizontales o verticales.

  • Cada vector tiene uno de estos cuatro puntos finales: ^v<>y está formado por un guión (- decimal 45) o una barra vertical ( |decimal 124).

  • Los puntos vacíos en el plano están llenos de espacios ( decimal 32).

  • La entrada puede ser un solo x .

  • Los vectores adyacentes son siempre perpendiculares entre sí.

  • Todos los vectores son de punta a cola.


Salida

Este será el desplazamiento del punto resultante (distancia desde el punto inicial) y el grado en que se ha movido, en relación con el punto inicial.

Para la entrada anterior, la salida debe ser 8.06unidades y 60.3grados. Cada uno debe tener exactamente 3 cifras significativas. Aquí hay algunos ejemplos de números con 3 dígitos significativos:

  • 1.00
  • 60,1
  • 453
  • 7.08
  • 4.50
  • 349

Todas las unidades de medida serán <= 999.


Estos números deben salir en el siguiente formato. Esto está usando los números de arriba.

8.06 units @ 60.3 degrees

Esto puede ser seguido por un solo espacio final o nueva línea.


Si la entrada es única x, sin desplazamiento y, por lo tanto, sin ángulo de desplazamiento, la salida debe ser una línea vacía (un solo carácter de nueva línea) o en el siguiente formato:

0 units @ - degrees

Si está tratando de calificar para el bono, la dirección también debería serlo -.


En el caso de que se completen las bonificaciones 2, 3 o ambas, la salida debe seguir el modelo a continuación y cumplir con las mismas restricciones que las anteriores.

8.06 units @ 60.3 degrees NE

Los grados deben medirse de acuerdo con el plano estándar.

       90
  135  |  45
      \|/
180 ---x---- 0
      /|\
  225  |  315
      270

0grados es este, 1 - 89grados es noreste, 90es norte, etc.


Bonos

Los siguientes valen un total de -50%.

  1. Obtenga una bonificación de -10% por cada vector adicional que pueda manejarse. Este bono se puede aplicar hasta 3 veces. Los vectores nunca se superpondrán ni se cruzarán.

  2. Obtenga una bonificación de -10% si su salida incluye la dirección cardinal del ángulo (norte, sur, este, oeste).

  3. Obtenga una bonificación de -10% si su salida incluye las direcciones intermedias del ángulo (noreste, noroeste, sureste, suroeste).


Ejemplos

En:

x---->
     |
     v

Fuera:

5.39 units @ 338 degrees

Opcionalmente SE


En:

<--------------^
               |
               |
               x

Fuera:

15.3 units @ 169 degrees

Opcionalmente NW


En:

x
|
|<-----^
|      |
v------>

Fuera:

2.24 units @ 297 degrees

Opcionalmente SE


Ejemplos (vectores múltiples)

En:

x--->
    |
    |
    v----------->

Fuera:

16.3 units @ 349 degrees

Opcionalmente SE


En:

<-------^
|       |
|       |
v       |
        |
        |
        x

Fuera:

8.54 units @ 159 degrees

Opcionalmente NW


En:

^-->
|  |
|  v
|
<--------x

Fuera:

6.32 units @ 162 degrees

Opcionalmente NW

Puertas de Zach
fuente
¿Los vectores tendrán alguna vez un componente cero en una dirección? Si es así, ¿para qué debería ser la salida x? ¿Cuál es el límite entre el norte y el noroeste?
lirtosiast el
He agregado esa información. ¡Gracias por mencionarlo! @ThomasKwa
Zach Gates
Debe agregar un caso de prueba donde solo haya un vector, por ejemplo x-->. ¿Se pueden cruzar los vectores?
lirtosiast
La entrada regular serán dos vectores. La única excepción es el vacío x. Puede haber más de dos (si intenta completar la bonificación), pero no menos. Estoy trabajando en ejemplos para múltiples entradas de vectores. En ninguna entrada se cruzarán los vectores. @ThomasKwa
Zach Gates
Los he agregado. @ThomasKwa
Zach Gates

Respuestas:

2

JavaScript (ES6), 305 bytes - 50% de bonificación = 152.5 puntaje

v=>(l=v.search`
`+1,s=v.search`x`,u=0,d="-",v.replace(/[<>v^]/g,(p,i)=>{c=o=>v[i+o]!=q;with(Math)if(p<"?"?c(l,q="|")&c(-l):c(1,q="-")&c(-1))d=(atan2(x=i%l-s%l,y=(i/l|0)-(s/l|0))*180/PI+270)%360,u=sqrt(x*x+y*y)}),u[p="toPrecision"](3)+` units @ ${d[p](3)} degrees`)

Explicación

La entrada debe estar rellenada con espacios. Utiliza todos los bonos.

v=>(
  l=v.search`
`+1,                                                     // l = line length
  s=v.search`x`,                                         // s = index of start point
  u=0,                                                   // u = units
  d=                                                     // d = degrees
  w="-",                                                 // w = cardinal direction
  v.replace(/[<>v^]/g,(p,i)=>{                           // for each endpoint
    c=o=>v[i+o]!=q;                                      // compares cell at offset to char
    with(Math)                                           // save having to write "Math."
      if(p<"?"?c(l,q="|")&c(-l):c(1,q="-")&c(-1))        // check for line branching off
        d=(atan2(
          x=i%l-s%l,                                     // x = relative x
          y=(i/l|0)-(s/l|0)                              // y = relative y
        )*180/PI+270)%360,                               // convert to degrees
        u=sqrt(x*x+y*y),
        w="N S"[sign(y)+1]+"W E"[sign(x)+1]              // get cardinal direction
  }),
  u[p="toPrecision"](3)+` units @ ${d[p](3)} degrees `+w // format output
)

Prueba

usuario81655
fuente
3

Python 2, 238.5 ( 594 562 482 477-50%) bytes

from math import*
def F(x):s='%.3g'%x;return[[s+'.',s]['.'in s].ljust(4,'0'),s][x>99]
I=input()
V=I.split('\n');N=len(V)
l=max(len(x)for x in V)
q=[' '*(l+2)];V=q+[' '+x.ljust(l+1)for x in V]+q
for k in range(N*l):
 i,j=k/l,k%l;c=V[i+1][j+1]
 if c in'<>^v'and['|'not in zip(*V)[j+1][i:i+3],'-'not in V[i+1][j:j+3]][c>'?']:a,b=i,j
 if c=='x':A,B=i,j
Y=A-a;X=b-B;a=atan2(Y,X)/pi*180%360
print[F(hypot(X,Y))+' units @ '+F(a)+' degrees '+' NS'[cmp(Y,0)]+' EW'[cmp(X,0)],''][I=='x']

Explicación

Encuentra las posiciones de inicio y final mirando cada personaje en la entrada.

Inicio es x

El final se encuentra mirando cada flecha (<>^v ) y sus vecinos. Si los vecinos son vectores continuos, ignore. De lo contrario, este es el final.

Mire a los vecinos perpendiculares a la dirección de la flecha.

Si contienen una línea perpendicular, entonces es un vector continuo.

Ejemplos ( _indica espacio):

_#_   
->_   Neighbors marked by #
_#_ 

___   
->_   (end)
___   

_|_   
->_   (not end)
___ 

___   
->|   (end)
___ 

---   
->_   (end)
___ 

Debido a que se encuentra el punto final, puede haber cualquier cantidad de vectores ( 30% de bonificación ).

TFeld
fuente
¿Estás seguro de que esto funciona en Python 2? Además, puede cambiar "de importación matemática " a "de importación matemática " (elimine el espacio).
Rɪᴋᴇʀ
@RikerW Funciona para mí. Ideone: ideone.com/9j86yj utiliza \ncomo saltos de línea ...
TFeld
Bien hecho, con una buena explicación de los "vecinos". Estaba un poco preocupado por su uso input()y el ajuste correspondiente de la entrada con "", ¡pero no parece haber una regla en contra!
Tim Pederick el