Euklidische Vektoren

14

Bestimmen Sie unter Berücksichtigung der ASCII-Kunst zweier Vektoren die Größe und den Grad des resultierenden Vektors.


Eingang

Dies kann über STDIN empfangen, aus einer lokalen Datei gelesen oder über einen Funktionsaufruf bereitgestellt werden. Hier ist ein Beispiel für eine Zwei-Vektor-Eingabe:

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

Dies entspricht einer Änderung von 4 Einheiten nach Norden und 7 Einheiten nach Osten. Der Startpunkt jeder Eingabe wird durch eine x(Dezimal 120) dargestellt.

  • Alle Vektoren sind horizontale oder vertikale Linien.

  • Jeder Vektor hat einen dieser vier Endpunkte: ^v<>und besteht entweder aus einem Strich ( -Dezimalzahl 45) oder einem vertikalen Strich ( |Dezimalzahl 124).

  • Leere Punkte in der Ebene werden mit Leerzeichen ( 32 Dezimalstellen) gefüllt .

  • Die Eingabe kann eine einzelne sein x.

  • Benachbarte Vektoren stehen immer senkrecht zueinander.

  • Alle Vektoren sind Tip-to-Tail.


Ausgabe

Dies ist die Verschiebung des resultierenden Punktes (Abstand vom Startpunkt) und der Grad, um den er sich relativ zum Startpunkt bewegt hat.

Für die obige Eingabe sollte die Ausgabe 8.06Einheiten und 60.3Grad sein. Jeder sollte genau 3 signifikante Zahlen haben. Hier einige Beispiele für Zahlen mit drei signifikanten Stellen:

  • 1.00
  • 60,1
  • 453
  • 7.08
  • 4,50
  • 349

Alle Maßeinheiten werden <= 999.


Diese Zahlen sollten im folgenden Format ausgegeben werden. Dies verwendet die Zahlen von oben.

8.06 units @ 60.3 degrees

Darauf kann ein einzelnes Leerzeichen oder eine neue Zeile folgen.


Wenn es sich bei der Eingabe um eine einzelne Eingabe xohne Verschiebung und daher ohne Verschiebungswinkel handelt, sollte die Ausgabe entweder eine leere Zeile (ein einzelnes Zeilenumbruchzeichen) oder das folgende Format aufweisen:

0 units @ - degrees

Wenn Sie versuchen, sich für den Bonus zu qualifizieren, sollte dies -auch die Richtung sein .


In dem Fall, dass die Boni 2, 3 oder beide abgeschlossen sind, sollte die Ausgabe dem folgenden Modell folgen und den gleichen Einschränkungen wie oben entsprechen.

8.06 units @ 60.3 degrees NE

Die Grade sollten gemäß der Standardebene gemessen werden.

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

0Grad ist Ost, 1 - 89Grad ist Nordost, 90ist Nord usw.


Boni

Die folgenden sind insgesamt -50% wert.

  1. Holen Sie sich einen Bonus von -10% für jeden weiteren Vektor, der bearbeitet werden kann. Dieser Bonus kann bis zu dreimal angewendet werden. Vektoren werden sich niemals überlappen oder kreuzen.

  2. Holen Sie sich einen Bonus von -10%, wenn Ihre Ausgabe die Hauptrichtung des Winkels (Nord, Süd, Ost, West) enthält.

  3. Holen Sie sich einen Bonus von -10%, wenn Ihre Ausgabe die Zwischenrichtungen des Winkels (Nordosten, Nordwesten, Südosten, Südwesten) enthält.


Beispiele

Im:

x---->
     |
     v

Aus:

5.39 units @ 338 degrees

Optional SE


Im:

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

Aus:

15.3 units @ 169 degrees

Optional NW


Im:

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

Aus:

2.24 units @ 297 degrees

Optional SE


Beispiele (mehrere Vektoren)

Im:

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

Aus:

16.3 units @ 349 degrees

Optional SE


Im:

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

Aus:

8.54 units @ 159 degrees

Optional NW


Im:

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

Aus:

6.32 units @ 162 degrees

Optional NW

Zach Gates
quelle
Werden Vektoren jemals eine Nullkomponente in einer Richtung haben? Wenn ja, wofür sollte die Ausgabe erfolgen x? Was ist die Grenze zwischen Nord und Nordwesten?
Lirtosiast
Ich habe diese Informationen hinzugefügt. Vielen Dank für den Hinweis! @ ThomasKwa
Zach Gates
Sie sollten einen Testfall hinzufügen, in dem nur ein Vektor vorhanden ist, z x-->. Können sich Vektoren kreuzen?
Lirtosiast
Die reguläre Eingabe besteht aus zwei Vektoren. Die einzige Ausnahme ist die leere x. Es kann mehr als zwei geben (wenn versucht wird, den Bonus zu vervollständigen), aber nicht weniger. Ich arbeite an Beispielen für mehrere Vektoreingaben. In keinem Fall kreuzen sich die Vektoren. @ ThomasKwa
Zach Gates
Ich habe sie hinzugefügt. @ ThomasKwa
Zach Gates

Antworten:

2

JavaScript (ES6), 305 Bytes - 50% Bonus = 152,5 Punkte

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

Erläuterung

Die Eingabe muss mit Leerzeichen aufgefüllt werden. Verwendet alle Boni.

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
)

Prüfung

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

Erläuterung

Findet die Start- und Endpositionen anhand der einzelnen Zeichen in der Eingabe.

Start ist x

Das Ende wird durch Betrachten der einzelnen Pfeile ( <>^v) und ihrer Nachbarn gefunden. Wenn Nachbarn weiterhin Vektoren verwenden, ignorieren Sie diese. Sonst ist das das Ende.

Schauen Sie sich die Nachbarn senkrecht zur Pfeilrichtung an.

Wenn sie eine senkrechte Linie enthalten, handelt es sich um einen fortlaufenden Vektor.

Beispiele ( _Leerzeichen):

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

___   
->_   (end)
___   

_|_   
->_   (not end)
___ 

___   
->|   (end)
___ 

---   
->_   (end)
___ 

Da der Endpunkt gefunden wird, kann es eine beliebige Anzahl von Vektoren geben ( 30% Bonus ).

TFeld
quelle
Sind Sie sicher, dass dies in Python 2 funktioniert? Außerdem können Sie "vom mathematischen Import " in "vom mathematischen Import " ändern (das Leerzeichen entfernen).
8.
@RikerW Es funktioniert bei mir. Ideone: ideone.com/9j86yj verwendet \nals Zeilenumbrüche ...
TFeld
Gut gemacht, mit einer schönen Erklärung der "Nachbarn". Ich war ein wenig besorgt über Ihre Verwendung von input()und das entsprechende Umbrechen der Eingabe mit "", aber es scheint keine Regel dagegen zu geben!
Tim Pederick