Skor satu anak panah

22

pengantar

Tulis program atau fungsi yang, dengan koordinat di mana anak panah mendarat di papan panah, kembalikan skor anak panah itu. Koordinat x,ydart diberikan sebagai dua bilangan bulat, diukur dari pusat papan dart, dengan presisi milimeter.

Cara mencetak anak panah

Darts adalah permainan yang dimainkan dengan melemparkan anak panah ke papan bundar. Papan panah dibagi menjadi 20 "wedges" berukuran sama. Mulai dari atas dan searah jarum jam, bagian memiliki nilai 20.1,18,4,13,6,10,15,2,17,3,19,7,16,8,11,14,9,12 , 5. Jika anak panah Anda mendarat di bagian hitam atau putih dari salah satu irisan, Anda mencetak nilai yang ditunjukkan di luar irisan itu.
inilah gambar papan dart.


Namun, jika panah Anda mendarat di cincin hijau / merah luar papan panah, Anda mencetak dua kali lipat poin yang ditunjukkan di luar irisan yang Anda pukul. Demikian juga, dengan memukul cincin hijau / merah bagian dalam (yang ada di antara dua bagian putih / hitam), Anda mencetak tiga kali lipat dari angka yang ditunjukkan di bagian luar irisan. Jika panah Anda mengenai lingkaran paling dalam (mata merah), Anda mencetak skor 50 poin dan akhirnya, jika panah Anda menyentuh lingkaran kedua yang paling dalam (cincin hijau di sekitar mata sapi), Anda mencetak 25 poin.

Dimensi cincin, diukur dari pusat papan dart, adalah sebagai berikut:

gambar tidak untuk skala


Bullseye (50): [0mm-6mm)
25:            [6mm-16mm)
Inner Single:  [16mm-99mm)
Triple:        [99mm-107mm)
Outer Single:  [107mm-162mm)
Double:        [162mm-170mm)
Miss (0):       170mm+

Catatan 1: Gambar yang disediakan hanya untuk tujuan ilustrasi, dan tidak untuk skala.

Catatan 2: Pengukuran yang diberikan merupakan perkiraan, dan mungkin tidak akurat untuk papan dart nyata.

Catatan 3: Semua pengukuran yang diberikan adalah [inclusive-exclusive). Untuk keperluan tantangan ini, kita tidak akan khawatir tentang panah yang mengenai kawat dan memantul. Jika anak panah mendarat "di kawat" dengan salah satu garis radial, maka tergantung pada penjawab untuk memutuskan apakah akan memutuskan ikatan searah jarum jam atau berlawanan arah jarum jam. Arah pemutusan ikatan harus konsisten, dan ditunjukkan.

Catatan 4: Papan Dart digantung dengan cara standar dengan bagian tengah 20 berada tepat di atas bullseye, dan 3 bagian langsung di bawah bullseye.

Memasukkan

Dua bilangan bulat yang mewakili x,ykoordinat tempat anak panah mendarat, diukur dalam milimeter, relatif terhadap bagian tengah papan panah.

Keluaran

Bilangan bulat tunggal, untuk jumlah poin yang akan diberikan kepada anak panah yang mendarat di koordinat yang diberikan.

Mencicipi

0,0     -> 50
2,101   -> 60
-163,-1 -> 22
6,18    ->  1
-6,18   ->  5
45,-169 ->  0
22, 22  ->  4 (if tie-broken clock-wise)
            18(if tie-broken counter-clockwise)
-150,0  ->  11
-150,-1 ->  11

Mencetak gol

. Byte paling sedikit dalam kode sumber Anda menang.

Celah standar dilarang .

mypetlion
sumber
1
@ Shaggy Saya tidak melihat alasan yang layak untuk melakukannya.
Jonathan Allan
5
@ Shaggy Bisakah Anda menjelaskan mengapa itu harus terjadi? Secara pribadi saya akan menyukainya jika anak panah saya selalu dijamin mengenai papan anak panah, tetapi demi tantangan, saya pikir yang terbaik adalah tetap berpegang pada kenyataan daripada fantasi.
mypetlion
1
Kasus uji yang disarankan: -150,-1dan -150,0yang harus memberi 11dan mungkin merupakan kasus tepi pada beberapa implementasi, karena ini adalah transisi antara theta konvergen ke -pi dan theta = + pi dalam koordinat polar. (Jawaban awal saya gagal pada jawaban ke-2.)
Arnauld
1
Dangit, x = y = 0 benar-benar membuatku kacau !! Tantangan bagus.
BradC
1
Semoga Anda tidak keberatan, saya mengedit dalam versi yang lebih baik dari pic kedua.
BradC

Jawaban:

19

JavaScript (ES7), 137 byte

Mengambil koordinat dalam sintaks currying (x)(y). Menggunakan tie-break berlawanan arah jarum jam.

x=>y=>(r=(x*x+y*y)**.5)<6?50:r<16?25:(r<99?1:r<107?3:r<162||r<170&&2)*parseInt('b8g7j3h2fa6d4i1k5c9eb'[Math.atan2(y,x)*3.1831+10.5|0],36)

Cobalah online!

Bagaimana?

Kami menerjemahkan input koordinat Cartesian ke dalam koordinat polar dengan:(x,y)(r,θ)

r=x2+y2
θ=Arktan2(y,x)

Kami menggunakan untuk menentukan apakah panah terletak di atas Bullseye , 25 , Single dalam , Triple , Outer Single , Double atau jika tembakannya adalah Miss .r

Jika kita berada di atas Tunggal , ganda atau triple , kita menggunakan untuk menentukan di mana sektor kita dengan:θs

s=θ+π2π×20+12=θ×10π+10+12

Untuk area , kita membutuhkan 4 tempat desimal untuk mendapatkan presisi yang cukup, yang menghasilkan:340×34010/π

10π3.1831

Skor basis disimpan berlawanan arah jarum jam dalam string yang dikodekan base-36 dari 21 entri, dimulai dan berakhir pada :11

11,8,16,7,19,3,17,2,15,10,6,13,4,18,1,20,5,12,9,14,11

Kita perlu mengulangi karena setengah dari sektor ini milik keping pertama (di mana dekat dengan ), sedangkan separuh lainnya milik keping terakhir (di mana dekat dengan ).θ - π θ + π11θ-πθ+π

Output grafis

Cuplikan kode ES6 berikut ini menggambar papan dart menggunakan logika yang sama seperti pada kode golf.

Arnauld
sumber
8

JavaScript (ES6) + SVG (HTML5), 53 + 523 51 + 519 507 = 576 570 558 byte

document.write`<svg width=345 height=345>`;i=b=Math.PI/10;s=Math.sin(a=-b/2);c=Math.cos(a);f=(r,f,n)=>document.write(`<path d=M172,172L${[172+r*s,172+r*c]}A${[r,r,0,0,1,172+r*t,172+r*d]}z fill=#${f} n=${n} />`);g=(q,r,m,n,i)=>f(q,i?474:`b32`,n*m)+f(r,i?`fff`:`000`,n);[3,17,2,15,10,6,13,4,18,1,20,5,12,9,14,11,8,16,7,19].map(n=>{t=s;d=c;s=Math.sin(a+=b);c=Math.cos(a);g(170,162,2,n,i=!i);g(107,99,3,n,i);});document.write`<circle cx=172 cy=172 r=16 fill=#474 n=25 /><circle cx=172 cy=172 r=6 fill=#b32 n=50`
<body onclick=alert(+event.target.getAttribute`n`)>

Input adalah melalui klik mouse, output melalui alert. Sunting: Disimpan 12 byte dengan menggunakan sedikit lebih banyak warna perkiraan seperti yang disarankan oleh @Arnauld.

Neil
sumber
Saya kira tidak ada yang akan menyalahkan Anda jika Anda menggunakan b33dan 474untuk merah dan hijau. :-)
Arnauld
@Arnauld Cukup adil, meskipun b33adalah bb3333begitu b22(alias bb3322) lebih dekat dengan asli Anda be3628.
Neil
7

Perakitan Intel 8086/8087, 180 144 142 138 byte

Ini menggunakan prosesor matematika 8087 untuk semua aritmetika trigonometri dan mengambang. Semua perhitungan dilakukan dalam perangkat keras dengan presisi floating-point 80-bit.

df06 b101 d8c8 df06 af01 d8c8 dec1 d9fa df1e b301 8b16 b301
33c0 81fa aa00 7c03 eb53 9083 fa06 7d05 b032 eb49 9083 fa10
7d05 b019 eb3f 90df 06b7 01df 06b5 01d9 f3df 06b1 01dd d2d9
ebde f9de c9de c1df 1eb3 01a1 b301 bb9c 01d7 83fa 6b7d 0a83
fa63 7c05 b303 eb09 9081 faa2 007c 04b3 02f6 e30b 0810 0713
0311 020f 0a06 0d04 1201 1405 0c09 0e0b 0a00

Ditulis sebagai MASRO MACRO (pada dasarnya fungsi), mengambil X dan Y sebagai koordinat dan mengembalikan skor yang dihitung dalam AX. Dasi rusak searah jarum jam.

MAX_BULL EQU 6
MAX_25   EQU 16
MIN_3X   EQU 99
MAX_3X   EQU 107
MIN_2X   EQU 162
MAX_2X   EQU 170

; cartesian coordinates to radius
; ST = sqrt( X^2 + Y^2 )
; input: X,Y (mem16,mem16)
; output: Radius (mem16)
FCRAD   MACRO X, Y, R
    FILD  Y         ; ST[] = Y
    FMUL  ST,ST     ; ST = y^2 
    FILD  X         ; ST[] = X
    FMUL  ST,ST     ; ST = x^2
    FADD            ; ST = ST + ST1
    FSQRT           ; ST = SQRT(ST)
    FISTP R         ; R = ROUND(ST)
        ENDM

; cartesian coordinates to sector #
; input: X,Y (mem16,mem16)
; output: Sector (mem16)
FCSEC   MACRO X, Y, S
    FILD  Y         ; ST[] = Y
    FILD  X         ; ST[] = X
    FPATAN          ; ST = atan2(Y,X)
    FILD  CTEN      ; ST[] = 10
    FST   ST(2)     ; ST(2) = 10
    FLDPI           ; ST[] = pi
    FDIV            ; ST = 10 / pi
    FMUL            ; ST = A * ST
    FADD            ; ST = ST + 10
    FISTP S         ; S = ROUND(ST)
        ENDM

; score the dart throw
; input: X / Y coordinates (mem16)
; output: Score (AX)
SCORE   MACRO X, Y
        LOCAL IS_BULL, IS_25, IS_3X, IS_2X, MUL_SCORE, DONE
    FCRAD X, Y, FDW         ; FDW = radius(X,Y)
    MOV  DX, FDW            ; DX = FDW = radius
    XOR  AX, AX             ; score is initially 0
    CMP  DX, MAX_2X         ; >= 170 (miss)
    JL   IS_BULL            ; if not, check for bullseye
    JMP  DONE
IS_BULL:
    CMP  DX, MAX_BULL       ; < 6 (inner bullseye)
    JGE  IS_25              ; if not, check for 25
    MOV  AL, 50             ; score is 50
    JMP  DONE
IS_25:
    CMP  DX, MAX_25         ; < 16 (outer bullseye)
    JGE  IS_3X              ; if not, check for triple
    MOV  AL, 25             ; score is 25
    JMP  DONE
IS_3X:
    FCSEC X, Y, FDW         ; FDW = sector(X,Y)
    MOV  AX, FDW            ; load sector # into AX
    MOV  BX, OFFSET SCR     ; load base score table
    XLAT                    ; put base score into AL
    CMP  DX, MAX_3X         ; < 107 (triple upper bounds)
    JGE  IS_2X              ; if not, check for double
    CMP  DX, MIN_3X         ; >= 99 (triple lower bounds)
    JL   IS_2X              ; if not, check for double
    MOV  BL, 3              ; this is triple score
    JMP  MUL_SCORE          ; go forth and multiply
IS_2X:
    CMP  DX, MIN_2X         ; >= 162 (double lower bounds) (> 170 already checked)
    JL   DONE               ; if not, single score
    MOV  BL, 2              ; this is double score
MUL_SCORE:
    MUL  BL                 ; multiply score either 2x or 3x
DONE:
    ENDM

; DATA (place in appropriate segment)
SCR     DB  11,8,16,7,19,3,17,2,15,10,6  ; score table
        DB  13,4,18,1,20,5,12,9,14,11
CTEN    DW  10      ; constant 10 to load into FPU
FDW     DW  ?       ; temp DW variable for CPU/FPU data transfer

Contoh program uji untuk PC DOS. Unduh di sini DARTTEST.COM .

INCLUDE DART.ASM            ; the above file
INCLUDE INDEC.ASM           ; generic I/O routines - input int
INCLUDE OUTDEC.ASM          ; generic I/O routines - output int

    FINIT                   ; reset 8087

    MOV  AH, 2              ; display "X" prompt
    MOV  DL, 'X'
    INT  21H
    CALL INDEC              ; read decimal for X into AX
    MOV  X, AX

    MOV  AH, 2              ; display "Y" prompt
    MOV  DL, 'Y'
    INT  21H
    CALL INDEC              ; read decimal for Y into AX
    MOV  Y, AX

    SCORE X, Y              ; AX = SCORE( X, Y )

    CALL OUTDEC             ; display score

X   DW  ?
Y   DW  ?

Keluaran

Contoh penggunaan program uji di atas . Diperlukan IBM PC aktual dengan 8087, DOSBox atau emulator favorit Anda.

A>DARTTEST.COM
X: 0
Y: 0
50
A>DARTTEST.COM
X: 2
Y: 101
60
A>DARTTEST.COM
X: -163
Y: -1
22
A>DARTTEST.COM
X: 6
Y: 18
1
A>DARTTEST.COM
X: -6
Y: 18
5
A>DARTTEST.COM
X: 45
Y: -169
0
A>DARTTEST.COM
X: 22
Y: 22
4
A>DARTTEST.COM
X: -150
Y: 0
11
A>DARTTEST.COM
X: -150
Y: 0
11
A>DARTTEST.COM
X: -150
Y: -1
11
A>DARTTEST.COM
X: -7
Y: -6
25
A>DARTTEST.COM
X: -90
Y: 138
24

* Suntingan:

  • -36 byte dengan menghapus pernyataan truncate-rounding dan 10,5 konstan. Ikat sekarang putus searah jarum jam.
  • -2 byte dengan menghapus tidak perlu lagi FRNDINT
  • -4 byte, FMUL menggunakan sumber / tujuan yang sama
640KB
sumber
6

Jelly , 56 byte

æA/Æ°_9:18ị“!@umÞẓẓS’Œ?¤
ḅıA<“©Ñckɱȥ‘TṂị“2ı¢¤¢£¡‘¹×>3$?Ç

Tautan monadik yang menerima pasangan sebagai daftar [x,y]yang menghasilkan skor.
Menggunakan searah jarum jam.

Cobalah online! Atau lihat test-suite

NB versi diad juga 56 byte

Bagaimana?

æA/Æ°_9:18ị“!@umÞẓẓS’Œ?¤ - Link 1, segment score: pair [x, y]
  /                      - reduce by:
æA                       -   arc tangent
   Æ°                    - convert from radians to degrees
     _9                  - subtract 9 (align 0 with boundary between 1 & 20)
       :18               - integer divide by 18 (yields a segment index from 0 to 19)
                       ¤ - nilad followed by link(s) as a nilad:
           “!@umÞẓẓS’    -   base 250 number = 2091180117530057584
                     Œ?  -   shortest permutation of natural numbers [1..N] which
                         -   would reside at that index in a list of all permutations of
                         -   those same numbers ordered lexicographically.
                         -   = [18,4,13,6,10,15,2,17,3,19,7,16,8,11,14,9,12,5,20,1]
          ị              - index into (yields the score associated with the segment)

ḅıA<“©Ñckɱȥ‘TṂị“2ı¢¤¢£¡‘¹×>3$?Ç - Main Link: segment score: pair [x, y]
 ı                              - √(-1)
ḅ                               - convert from base = x+iy
  A                             - absolute value = √(x²+y²)
    “©Ñckɱȥ‘                    - code-page index list = [6,16,99,107,162,170]
                                - (i.e. the radial boundaries)
            T                   - list of truthy indexes
             Ṃ                  - minimal value (0 if empty)
               “2ı¢¤¢£¡‘        - code-page index list = [50,25,1,3,1,2,0]
              ị                 - index into
                                - (i.e. get an override score (>3) OR a multiplier (<=3))
                              Ç - call last Link (1) as a monad (get the segment score)
                             ?  - if...
                            $   - ...condition: last two links as a monad:
                          >     -      (override OR multiplier) greater than?
                           3    -      three
                        ¹       - ...then: identity (keep override as is)
                         ×      - ...else: multiply (by multiplier)
Jonathan Allan
sumber
4

TI-Basic (TI-84 Plus CE), 147 146 byte

Prompt X,Y
abs(X+iY→R
int(E-12+11.5+10π-1R▸Pθ(X,Y→θ
{11,8,16,7,19,3,17,2,15,10,6,13,4,18,1,20,5,12,9,14,11
25((R<6)+(R<16))+Ans(θ)(R≥16 and R<170)(1+(R≥162)+2(R≥99 and R<107

Anjuran untuk X dan Y pada jalur terpisah.

Ikat-putus berlawanan arah jarum jam.

TI-Basic adalah bahasa tokenized ; semua token yang digunakan di sini adalah satu byte.

Penjelasan:

Prompt X,Y
# 5 bytes, Prompt for X and Y
abs(X+iY→R
# 8 bytes, store distance from origin in R
int(E-12+11.5+10π-1R▸Pθ(X,Y→θ
# 22 bytes, store index in list of point values by polar angle in θ
{11,8,16,7,19,3,17,2,15,10,6,13,4,18,1,20,5,12,9,14,11
# 55 bytes, list of point values
25((R<6)+(R<16))+Ans(θ)(R≥16 and R<170)(1+(R≥162)+2(R≥99 and R<107
# 57 56 bytes, calculate the score

Memanfaatkan fakta bahwa perbandingan boolean TI-Basic menghasilkan 0 atau 1 dengan menambahkannya dan mengalikannya dengan nilai poin.

pizzapants184
sumber
3

T-SQL, 392 374 366 byte

UPDATE t SET x=1WHERE x=0
SELECT TOP 1IIF(r<16,f,b*f)
FROM(SELECT r=SQRT(x*x+y*y),w=FLOOR(10*ATN2(y,x)/PI()+.5)FROM t)p,
(VALUES(10,11),(9,14),(8,9),(7,12),(6,5),(5,20),(4,1),(3,18),(2,4),(1,13),(0,6),
   (-1,10),(-2,15),(-3,2),(-4,17),(-5,3),(-6,19),(-7,7),(-8,16),(-9,8),(-10,11))s(a,b),
(VALUES(6,50),(16,25),(99,1),(107,3),(162,1),(170,2),(999,0))d(e,f)
WHERE a=w AND r<e

Jeda baris adalah untuk keterbacaan. Awal UPDATEmenangani x=y=0masalah yang jika tidak akan menimbulkan kesalahan ATN2(), tetapi tidak mengubah skor.

Input diambil melalui tabel t yang sudah ada , sesuai pedoman IO kami . Karena menggunakan TOP 1, tabel ini hanya boleh berisi satu baris.

Pada dasarnya saya bergabung dengan 3 tabel:

  • Tabel p : X dan y dari tabel input t dikonversi ke nilai polar r dan "wedge" w yang mewakili angka dari -11 hingga positif 11, untuk wedge skor yang digunakan panah. "Tie breaker" berlawanan arah jarum jam. (Saya mencoba ROUND(), yang sedikit lebih pendek, tetapi itu memberikan tie breaker yang tidak konsisten.)
  • Tabel s : Ini adalah tabel untuk mengkonversi "wedge" nilai yang menjadi nilai b .
  • Tabel d : Ini adalah tabel pencarian yang mengembalikan perhitungan skor berdasarkan jarak dari pusat. e adalah jarak dan bergabung ke r , dan hanya mengembalikan satu baris berdasarkan TOP 1. Nilai f adalah skor tetap (untuk bulls-eye) atau pengali untuk skor irisan.

EDIT : Menjatuhkan ORDER BY, tampaknya berfungsi dengan baik tanpanya, setidaknya pada SQL 2017. Saya juga menjatuhkan AND y=0pada kondisi pembaruan; Saya menguji semua ynilai integer , berubah x=0menjadi x=1tidak pernah mengubah skor.

EDIT 2 : Menghapus kolom g dari tabel d , menggantinya dengan IIF()pernyataan yang mengembalikan flangsung (untuk mata bulls), atau f*b, menyimpan 8 byte. Juga menghapus ruang setelah TOP 1.

BradC
sumber
2

Haskell , 198 byte

p=pure
a#b=(!!(sum[1|k<-a,k<=b]))
a!b=([6,16,99,107,162,170]#(sqrt$a*a+b*b))[p 50,p 25,id,(*3),id,(*2),p 0]$([pi/20,3*pi/20..6]#(pi+atan2 b a))[11,8,16,7,19,3,17,2,15,10,6,13,4,18,1,20,5,12,9,14,11]

Tie rusak berlawanan arah jarum jam. (#)adalah fungsi pencarian. Sudut kutub digunakan untuk mengindeks dari daftar angka, mulai dari atan2titik cutoff di 11. Jarak digunakan untuk mengindeks dari daftar fungsi [const 50, const 25, id, (*3), id, (*2), const 0]dan akhirnya fungsi ini diterapkan ke nomor yang sebelumnya kita dapatkan.

Cobalah online!

Angs
sumber
1

Perl 5 -MMath::Trig':pi' -MMath::Trig':radial' -apl , 166 byte

($d,$a)=cartesian_to_cylindrical@F;$_=(1+($d>161||$d<6)+($d<107&&$d>98)*2)*($d<170)*($d<16?25:("6 134 181 205 129 14118 167 193 172 1510"=~/../g)[($a/pi*10+41/2)%20])

Cobalah online!

Membawa dua koordinat ruang terpisah pada STDIN. Tie-breaking berlawanan arah jarum jam.

Xcali
sumber