유클리드 벡터


14

두 벡터의 ASCII 기술이 주어지면 결과 벡터의 크기와 정도를 찾으십시오.


입력

이것은 STDIN을 통해 수신되거나 로컬 파일에서 읽거나 함수 호출을 통해 제공 될 수 있습니다. 다음은 두 개의 벡터 입력 예입니다.

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

이것은 북쪽으로 4 대, 동쪽으로 7 대의 변화를 나타냅니다. 모든 입력의 시작점은 x(소수점 120) 으로 표시됩니다 .

  • 모든 벡터는 가로 또는 세로 선입니다.

  • 각 벡터에는 다음 네 가지 끝점 중 하나가 있습니다. ^v<>, 대시 ( -, 십진수 45) 또는 세로 막대 ( |, 십진수 124)로 구성됩니다.

  • 평면의 빈 점은 공백으로 채워집니다 ( , 10 진수 32).

  • 입력은 단일 일 수 있습니다 x.

  • 인접한 벡터는 항상 서로 수직입니다.

  • 모든 벡터는 끝에서 끝까지입니다.


산출

이것은 결과 점 (시작점으로부터의 거리)의 변위와 시작점에 대한 점의 이동 정도입니다.

위 입력의 경우 출력은 8.06단위와 60.3도 여야합니다 . 각각 3 개의 유효 숫자가 있어야합니다. 유효 숫자가 3 개인 숫자의 예는 다음과 같습니다.

  • 1.00
  • 60.1
  • 453
  • 7.08
  • 4.50
  • 349

모든 단위 측정은입니다 <= 999.


이 숫자는 아래 형식으로 출력되어야합니다. 위의 숫자를 사용하고 있습니다.

8.06 units @ 60.3 degrees

그 뒤에 단일 후행 공백이나 줄 바꿈이 올 수 있습니다.


입력이 x변위가없고 변위 각이없는 단일 인 경우 출력은 빈 줄 (한 줄 바꿈 문자)이거나 다음 형식이어야합니다.

0 units @ - degrees

보너스를 받으려면 방향 -도 잘 따라야합니다 .


보너스 2, 3 또는 둘 다 완료된 경우 출력은 아래 모델을 따르고 위와 동일한 제한을 따라야합니다.

8.06 units @ 60.3 degrees NE

정도는 표준 평면에 따라 측정해야합니다.

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

0도는 동쪽, 1 - 89도는 북동쪽, 90북쪽 등입니다.


보너스

다음은 총 -50 %의 가치가 있습니다.

  1. 처리 할 수있는 각 추가 벡터에 대해 -10 %의 보너스를받습니다. 이 보너스는 최대 3 번까지 적용 할 수 있습니다. 벡터는 절대 겹치거나 교차하지 않습니다.

  2. 출력에 각도의 기본 방향 (북쪽, 남쪽, 동쪽, 서쪽)이 포함 된 경우 -10 % 보너스를받습니다.

  3. 출력에 각도의 중간 방향 (동북쪽, 북서쪽, 남동쪽, 남서쪽)이 포함 된 경우 -10 % 보너스를받습니다.


에:

x---->
     |
     v

밖:

5.39 units @ 338 degrees

선택적으로 SE


에:

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

밖:

15.3 units @ 169 degrees

선택적으로 NW


에:

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

밖:

2.24 units @ 297 degrees

선택적으로 SE


예 (여러 벡터)

에:

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

밖:

16.3 units @ 349 degrees

선택적으로 SE


에:

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

밖:

8.54 units @ 159 degrees

선택적으로 NW


에:

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

밖:

6.32 units @ 162 degrees

선택적으로 NW


벡터가 한 방향으로 성분이 없을까요? 그렇다면 무엇을 출력해야 x합니까? 북서부와 북서부 사이의 경계는 무엇입니까?
lirtosiast

그 정보를 추가했습니다. 지적 해 주셔서 감사합니다! @ThomasKwa
Zach Gates

벡터가 하나 뿐인 테스트 사례를 추가해야합니다 (예 :) x-->. 벡터가 교차 할 수 있습니까?
lirtosiast

정규 입력은 두 벡터입니다. 단일 예외는 비어 x있습니다. 보너스를 완료하려고 시도하는 경우 둘 이상이있을 수 있지만 그보다 적지는 않습니다. 여러 벡터 입력에 대한 예제를 작성 중입니다. 입력이 없으면 벡터가 교차하지 않습니다. @ThomasKwa
Zach Gates

내가 추가했습니다. @ThomasKwa
Zach Gates

답변:


2

자바 스크립트 (ES6), 305 바이트-50 % 보너스 = 152.5 점

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

설명

입력은 공백으로 채워 져야합니다. 모든 보너스를 사용합니다.

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
)

테스트


3

파이썬 2, 238.5 ( 594 562 482 477~50%는) 바이트

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

설명

입력의 각 문자를보고 시작 및 끝 위치를 찾습니다.

시작은 x

끝은 각 화살표 ( <>^v)와 해당 이웃 을 보면 찾을 수 있습니다. 이웃이 계속되는 벡터 인 경우 무시하십시오. 그렇지 않으면 이것이 끝입니다.

화살표 방향에 수직 인 이웃을보십시오.

수직선이 포함되어 있으면 계속되는 벡터입니다.

예 ( _공백을 나타냄) :

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

___   
->_   (end)
___   

_|_   
->_   (not end)
___ 

___   
->|   (end)
___ 

---   
->_   (end)
___ 

종점이 발견되었으므로 벡터 수 ( 30 % 보너스 ) 가있을 수 있습니다 .


이것이 파이썬 2에서 작동합니까? 또한 "수학 가져 오기 "에서 " 수학 가져 오기 "로 변경할 수 있습니다 (공백 제거).
Rɪᴋᴇʀ

@RikerW 그것은 나를 위해 작동합니다. Ideone : ideone.com/9j86yj줄 바꿈으로 사용합니다 \n...
TFeld

"이웃들"에 대한 좋은 설명으로 잘 끝났습니다. 나는 당신의 사용 input()과 ""로 입력의 상응하는 줄 바꿈에 대해 약간 걱정 했지만, 그것에 대한 규칙은없는 것 같습니다!
Tim Pederick
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.