Vektor Euclidean

14

Mengingat seni ASCII dari dua vektor, cari besaran dan derajat vektor yang dihasilkan.


Memasukkan

Ini dapat diterima melalui STDIN, membaca dari file lokal, atau disediakan melalui panggilan fungsi. Berikut adalah contoh input vektor dua:

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

Ini mewakili perubahan 4 unit utara dan 7 unit timur. Setiap titik awal input akan diwakili oleh x(desimal 120).

  • Semua vektor adalah garis horizontal atau vertikal.

  • Setiap vektor memiliki salah satu dari empat titik akhir ini:, ^v<>dan terdiri dari tanda hubung ( -, desimal 45) atau bilah vertikal ( |, desimal 124).

  • Poin kosong di pesawat diisi dengan spasi ( , desimal 32).

  • Input mungkin satu x.

  • Vektor yang berdekatan selalu saling tegak lurus.

  • Semua vektor tip-to-tail.


Keluaran

Ini akan menjadi perpindahan dari titik yang dihasilkan (jarak dari titik awal) dan sejauh mana ia telah bergerak, relatif terhadap titik awal.

Untuk input di atas, output harus 8.06satuan dan 60.3derajat. Masing-masing harus memiliki tepat 3 angka signifikan. Berikut adalah beberapa contoh angka dengan 3 digit signifikan:

  • 1,00
  • 60.1
  • 453
  • 7.08
  • 4,50
  • 349

Semua pengukuran unit akan dilakukan <= 999.


Angka-angka ini harus berupa output dalam format di bawah ini. Ini menggunakan angka-angka dari atas.

8.06 units @ 60.3 degrees

Ini dapat diikuti oleh satu spasi tambahan atau baris baru.


Jika input adalah tunggal x, tanpa perpindahan dan karenanya tidak ada sudut perpindahan, output harus berupa baris kosong (karakter baris baru tunggal) atau dalam format berikut:

0 units @ - degrees

Jika Anda mencoba memenuhi syarat untuk bonus, arahnya juga harus -.


Dalam hal bonus 2, 3, atau keduanya selesai, output harus mengikuti model di bawah ini dan mematuhi batasan yang sama seperti di atas.

8.06 units @ 60.3 degrees NE

Derajat harus diukur sesuai dengan bidang standar.

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

0derajat adalah timur, 1 - 89derajat timur laut, 90utara, dll.


Bonus

Berikut ini bernilai total -50%.

  1. Ambil bonus -10% untuk setiap vektor tambahan yang dapat ditangani. Bonus ini dapat diterapkan hingga 3 kali. Vektor tidak akan pernah tumpang tindih atau menyeberang.

  2. Ambil bonus -10% jika output Anda menyertakan arah mata angin dari sudut (utara, selatan, timur, barat).

  3. Ambil bonus -10% jika output Anda menyertakan arah tengah sudut (timur laut, barat laut, tenggara, barat daya).


Contohnya

Di:

x---->
     |
     v

Di luar:

5.39 units @ 338 degrees

Opsional SE


Di:

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

Di luar:

15.3 units @ 169 degrees

Opsional NW


Di:

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

Di luar:

2.24 units @ 297 degrees

Opsional SE


Contoh (beberapa vektor)

Di:

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

Di luar:

16.3 units @ 349 degrees

Opsional SE


Di:

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

Di luar:

8.54 units @ 159 degrees

Opsional NW


Di:

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

Di luar:

6.32 units @ 162 degrees

Opsional NW

Zach Gates
sumber
Apakah vektor pernah memiliki komponen nol dalam satu arah? Jika demikian, untuk apa hasilnya x? Apa batas antara Utara dan Barat Laut?
lirtosiast
Saya telah menambahkan informasi itu. Terima kasih telah menunjukkannya! @ThomasKwa
Zach Gates
Anda harus menambahkan test case di mana hanya ada satu vektor, mis x-->. Bisakah vektor melintas?
lirtosiast
Input reguler akan menjadi dua vektor. Satu-satunya pengecualian adalah yang kosong x. Mungkin ada lebih dari dua (jika berusaha menyelesaikan bonus), tetapi tidak kurang. Saya sedang mengerjakan contoh untuk beberapa input vektor. Dalam input tidak akan vektor lintas. @ThomasKwa
Zach Gates
Saya sudah menambahkannya. @ThomasKwa
Zach Gates

Jawaban:

2

JavaScript (ES6), 305 byte - 50% bonus = skor 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`)

Penjelasan

Input harus diisi dengan spasi. Gunakan semua 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
)

Uji

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

Penjelasan

Temukan posisi awal dan akhir dengan melihat setiap karakter dalam input.

Mulai adalah x

Akhir ditemukan dengan melihat setiap panah ( <>^v), dan tetangga mereka. Jika tetangga melanjutkan vektor, abaikan. Lain, ini akhirnya.

Lihatlah tetangga yang tegak lurus dengan arah panah.

Jika mereka mengandung garis tegak lurus, maka itu adalah vektor yang berkelanjutan.

Contoh ( _menunjukkan spasi):

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

___   
->_   (end)
___   

_|_   
->_   (not end)
___ 

___   
->|   (end)
___ 

---   
->_   (end)
___ 

Karena titik akhir ditemukan, mungkin ada sejumlah vektor ( bonus 30% ).

TFeld
sumber
Apakah Anda yakin ini bekerja di python 2? Plus, Anda dapat mengubah "dari impor matematika " menjadi "dari impor matematika " (menghapus spasi).
R
@RikerW Ini bekerja untuk saya. Ideone: ideone.com/9j86yj menggunakan \nsebagai linebreak ...
TFeld
Bagus, dengan penjelasan yang bagus tentang "tetangga". Saya agak khawatir dengan penggunaan Anda input()dan pembungkus input yang sesuai dengan "", tetapi sepertinya tidak ada aturan yang melarangnya!
Tim Pederick