Vettori euclidei


14

Data l'arte ASCII di due vettori, trova la grandezza e il grado del vettore risultante.


Ingresso

Questo può essere ricevuto tramite STDIN, letto da un file locale o fornito tramite una chiamata di funzione. Ecco un esempio di un input di due vettori:

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

Ciò rappresenta un cambiamento di 4 unità a nord e 7 unità a est. Il punto iniziale di ogni input sarà rappresentato da un x(decimale 120).

  • Tutti i vettori sono linee orizzontali o verticali.

  • Ogni vettore ha uno di questi quattro punti finali: ^v<>ed è costituito da un trattino ( -, 45 decimale) o da una barra verticale ( |, 124 decimale).

  • I punti vuoti sul piano sono riempiti di spazi ( , decimale 32).

  • L'input può essere un singolo x.

  • I vettori adiacenti sono sempre perpendicolari tra loro.

  • Tutti i vettori sono da punta a coda.


Produzione

Questo sarà lo spostamento del punto risultante (distanza dal punto iniziale) e il grado in cui si è spostato, rispetto al punto iniziale.

Per l'input sopra, l'output dovrebbe essere 8.06unità e 60.3gradi. Ognuno dovrebbe avere esattamente 3 cifre significative. Ecco alcuni esempi di numeri con 3 cifre significative:

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

Tutte le misure dell'unità saranno <= 999.


Questi numeri dovrebbero essere emessi nel formato seguente. Questo sta usando i numeri dall'alto.

8.06 units @ 60.3 degrees

Questo può essere seguito da un singolo spazio finale o da una nuova riga.


Se l'input è un singolo x, senza spostamento e quindi senza angolo di spostamento, l'output dovrebbe essere una riga vuota (un singolo carattere di nuova riga) o nel seguente formato:

0 units @ - degrees

Se stai cercando di qualificarti per il bonus, anche la direzione dovrebbe essere -.


Nel caso in cui i bonus 2, 3 o entrambi siano completati, l'output dovrebbe seguire il modello seguente e rispettare le stesse restrizioni di cui sopra.

8.06 units @ 60.3 degrees NE

I gradi dovrebbero essere misurati secondo il piano standard.

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

0gradi è est, 1 - 89gradi è nord-est, 90è nord, ecc.


bonus

Quanto segue vale un totale di -50%.

  1. Prendi un bonus del -10% per ogni vettore aggiuntivo che può essere gestito. Questo bonus può essere applicato fino a 3 volte. I vettori non si sovrappongono mai o si incrociano.

  2. Prendi un bonus del -10% se l'output include la direzione cardinale dell'angolo (nord, sud, est, ovest).

  3. Prendi un bonus del -10% se la tua uscita include le direzioni intermedie dell'angolo (nord-est, nord-ovest, sud-est, sud-ovest).


Esempi

Nel:

x---->
     |
     v

Su:

5.39 units @ 338 degrees

facoltativamente SE


Nel:

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

Su:

15.3 units @ 169 degrees

facoltativamente NW


Nel:

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

Su:

2.24 units @ 297 degrees

facoltativamente SE


Esempi (più vettori)

Nel:

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

Su:

16.3 units @ 349 degrees

facoltativamente SE


Nel:

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

Su:

8.54 units @ 159 degrees

facoltativamente NW


Nel:

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

Su:

6.32 units @ 162 degrees

facoltativamente NW


I vettori avranno mai una componente zero in una direzione? In tal caso, a cosa dovrebbe servire l'output x? Qual è il confine tra nord e nord-ovest?
lirtosiast

Ho aggiunto queste informazioni. Grazie per segnalarlo! @ThomasKwa
Zach Gates

È necessario aggiungere un caso di test in cui sia presente un solo vettore, ad es x-->. I vettori possono attraversare?
lirtosiast

L'input regolare sarà di due vettori. L'unica eccezione è il vuoto x. Potrebbero essercene più di due (se si tenta di completare il bonus), ma non di meno. Sto lavorando ad esempi per più input vettoriali. In nessun caso i vettori si incrociano. @ThomasKwa
Zach Gates

Li ho aggiunti. @ThomasKwa
Zach Gates

Risposte:


2

JavaScript (ES6), 305 byte - 50% di bonus = 152,5 punti

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

Spiegazione

L'ingresso deve essere riempito di spazi. Usa tutti i bonus.

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
)

Test


3

Python 2, 238,5 ( 594 562 482 477-50%) byte

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']

Spiegazione

Trova le posizioni iniziale e finale osservando ciascun carattere nell'input.

L'inizio è x

L'estremità si trova guardando ogni freccia (<>^v ) e i loro vicini. Se i vicini continuano i vettori, ignorare. Altrimenti, questa è la fine.

Guarda i vicini perpendicolari alla direzione della freccia.

Se contengono una linea perpendicolare, allora è un vettore continuo.

Esempi ( _indica lo spazio):

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

___   
->_   (end)
___   

_|_   
->_   (not end)
___ 

___   
->|   (end)
___ 

---   
->_   (end)
___ 

Poiché viene trovato il punto finale, può esserci un numero qualsiasi di vettori ( bonus del 30% ).


Sei sicuro che funzioni in Python 2? Inoltre, puoi cambiare "dall'importazione matematica " a "dall'importazione matematica " (rimuovi lo spazio).
Rɪᴋᴇʀ

@RikerW Funziona per me. Ideone: ideone.com/9j86yj usa \ncome interruzioni di
riga

Ben fatto, con una bella spiegazione dei "vicini". Ero un po 'preoccupato per il tuo uso input()e il corrispondente avvolgimento dell'input con "", ma non sembra esserci una regola contro di esso!
Tim Pederick,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.