Điểm một phi tiêu


22

Giới thiệu

Viết chương trình hoặc hàm, với tọa độ nơi phi tiêu rơi trên phi tiêu, trả về điểm của phi tiêu đó. Tọa độ phi tiêu được đưa ra dưới dạng hai số nguyên, x,yđược đo từ tâm của bảng phi tiêu, với độ chính xác đến từng milimet.

Làm thế nào để ghi một phi tiêu

Phi tiêu là một trò chơi được chơi bằng cách ném phi tiêu vào một bảng tròn. Bảng phi tiêu được chia thành 20 "nêm" có kích thước bằng nhau. Bắt đầu từ đầu và đi theo chiều kim đồng hồ, các phần có các giá trị 20,1,18,4,13,6,10,15,2,17,3,19,7,16,8,11,14,9,12 , 5. Nếu phi tiêu của bạn rơi vào các phần màu đen hoặc trắng của bất kỳ nêm nào, bạn sẽ ghi được giá trị được chỉ ra ở bên ngoài nêm đó.
đây là hình ảnh của một phi tiêu.


Tuy nhiên, nếu phi tiêu của bạn rơi vào vòng màu xanh lá cây / đỏ bên ngoài của bảng phi tiêu, bạn sẽ ghi được gấp đôi số điểm được chỉ ra ở bên ngoài nêm mà bạn đánh. Tương tự như vậy, nhấn vào vòng màu lục / đỏ bên trong (phần nằm giữa hai phần trắng / đen), bạn ghi được gấp ba số được chỉ định ở bên ngoài nêm. Nếu phi tiêu của bạn chạm vào vòng tròn trong cùng (mắt bò đỏ), thay vào đó bạn ghi được 50 điểm và cuối cùng, nếu phi tiêu của bạn chạm vào vòng tròn trong cùng thứ hai (vòng màu xanh lá cây quanh mắt bò), bạn sẽ ghi được 25 điểm.

Kích thước của các vòng, được đo từ tâm của bảng phi tiêu, như sau:

hình ảnh không theo tỷ lệ


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

Lưu ý 1: Hình ảnh được cung cấp chỉ nhằm mục đích minh họa và không được chia tỷ lệ.

Lưu ý 2: Các phép đo được đưa ra là gần đúng và có thể không chính xác với bảng phi tiêu thực.

Lưu ý 3: Tất cả các phép đo được đưa ra là [inclusive-exclusive). Đối với mục đích của thử thách này, chúng tôi sẽ không lo lắng về việc phi tiêu chạm dây và bật ra. Nếu phi tiêu hạ cánh "trên dây" với một trong các đường xuyên tâm, thì người trả lời sẽ quyết định xem có nên phá vỡ dây buộc theo chiều kim đồng hồ hay ngược chiều kim đồng hồ. Hướng phá vỡ cà vạt phải nhất quán, và chỉ định.

Lưu ý 4: Bảng quảng cáo được treo theo cách tiêu chuẩn với phần giữa của phần 20 nằm ngay phía trên hình chữ nhật và phần 3 ngay bên dưới hình chữ nhật.

Đầu vào

Hai số nguyên biểu thị x,ytọa độ nơi phi tiêu hạ cánh, được đo bằng milimét, so với tâm của bảng phi tiêu.

Đầu ra

Một số nguyên duy nhất, cho số điểm sẽ được trao cho một phi tiêu hạ cánh tại tọa độ đã cho.

Mẫu vật

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

Chấm điểm

. Ít byte nhất trong mã nguồn của bạn thắng.

Sơ hở tiêu chuẩn bị cấm .


1
@Shaggy Tôi không thấy bất kỳ lý do chính đáng để làm như vậy.
Jonathan Allan

5
@Shaggy Bạn có thể giải thích tại sao nên như vậy không? Cá nhân tôi sẽ thích nó nếu phi tiêu của tôi luôn được đảm bảo để bắn bảng phi tiêu, nhưng vì thách thức, tôi nghĩ tốt nhất nên bám vào thực tế hơn là tưởng tượng.
mypetlion

1
Các trường hợp thử nghiệm được đề xuất: -150,-1-150,0cả hai nên cho 11và có thể là trường hợp cạnh trên một số triển khai, vì đây là chuyển đổi giữa theta hội tụ đến -pi và theta = + pi trong tọa độ cực. (Câu trả lời ban đầu của tôi đã thất bại ở lần thứ 2.)
Arnauld

1
Dangit, x = y = 0 hoàn toàn làm tôi bối rối !! Thử thách tốt.
BradC

1
Hy vọng bạn không phiền, tôi đã chỉnh sửa trong phiên bản tốt hơn của ảnh thứ hai.
BradC

Câu trả lời:


19

JavaScript (ES7), 137 byte

Lấy tọa độ trong cú pháp currying (x)(y). Sử dụng tie-break ngược chiều kim đồng hồ.

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)

Hãy thử trực tuyến!

Làm sao?

(x,y)(r,θ)

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

r

θs

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

340×34010/π

10π3.1831

11

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

11θπθ+π

Đầu ra đồ họa

Đoạn mã ES6 sau đây vẽ bảng phi tiêu bằng cách sử dụng logic tương tự như trong mã được đánh gôn.


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

Đầu vào là thông qua nhấp chuột, đầu ra thông qua alert. Chỉnh sửa: Đã lưu 12 byte bằng cách sử dụng các màu gần đúng hơn một chút theo đề xuất của @Arnauld.


Tôi đoán không ai sẽ đổ lỗi cho bạn nếu bạn sử dụng b33474cho màu đỏ và màu xanh lá cây. :-)
Arnauld

@Arnauld Hội chợ đủ, mặc dù b33bb3333như vậy b22(aka bb3322) là gần gũi hơn với ban đầu của bạn be3628.
Neil

7

Lắp ráp Intel 8086/8087, 180 144 142 138 byte

Điều này sử dụng bộ đồng xử lý toán học 8087 cho tất cả các số học trig và dấu phẩy động. Tất cả các tính toán được thực hiện trong phần cứng với độ chính xác điểm nổi 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

Được viết dưới dạng MACM MACRO (về cơ bản là một hàm), lấy X và Y làm tọa độ và trả về số điểm được tính trong AX. Cà vạt bị hỏng theo chiều kim đồng hồ.

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

Một chương trình thử nghiệm ví dụ cho PC DOS. Tải xuống tại đây 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  ?

Đầu ra

Ví dụ sử dụng chương trình thử nghiệm ở trên . IBM PC thực tế với 8087, DOSBox hoặc trình giả lập yêu thích của bạn được yêu cầu.

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

* Chỉnh sửa:

  • -36 byte bằng cách loại bỏ câu lệnh làm tròn cắt và hằng số 10,5. Tie bây giờ bị hỏng theo chiều kim đồng hồ.
  • -2 byte bằng cách loại bỏ FRNDINT không còn cần thiết
  • -4 byte, FMUL sử dụng cùng nguồn / đích

6

Thạch , 56 byte

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

Một liên kết đơn âm chấp nhận cặp như một danh sách [x,y]mang lại điểm số.
Sử dụng theo chiều kim đồng hồ.

Hãy thử trực tuyến! Hoặc xem bộ thử nghiệm

NB một phiên bản dyadic cũng là 56 byte

Làm sao?

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

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

Nhắc cho X và Y trên các dòng riêng biệt.

Tie-break ngược chiều kim đồng hồ.

TI-Basic là ngôn ngữ được mã hóa ; tất cả các mã thông báo được sử dụng ở đây là một byte.

Giải trình:

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

Sử dụng thực tế là các phép so sánh boolean TI-Basic trả về 0 hoặc 1 bằng cách thêm chúng lên và nhân với các giá trị điểm.


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

Ngắt dòng là để dễ đọc. Ban đầu UPDATEquan tâm đến x=y=0vấn đề có thể gây ra lỗi ATN2(), nhưng không thay đổi điểm số.

Đầu vào được lấy thông qua bảng t có sẵn , theo hướng dẫn IO của chúng tôi . Do sử dụng TOP 1, bảng này chỉ chứa một hàng.

Về cơ bản tôi đang tham gia 3 bảng:

  • Bảng p : xy từ bảng đầu vào t được chuyển đổi thành cực r và giá trị "nêm" w đại diện cho một số từ -11 đến 11 dương, cho điểm nêm mà phi tiêu rơi vào. "Tie breaker" là ngược chiều kim đồng hồ. (Tôi đã thử ROUND(), nó ngắn hơn một chút, nhưng nó đã cho một bộ ngắt kết nối không nhất quán.)
  • Bảng s : Đây là bảng tra cứu để chuyển đổi giá trị "nêm" a thành điểm b .
  • Bảng d : Đây là bảng tra cứu trả về phép tính điểm dựa trên khoảng cách từ tâm. e là khoảng cách và tham gia vào r và chỉ trả về một hàng duy nhất dựa trên TOP 1. Giá trị f là điểm cố định (đối với mắt bò) hoặc hệ số nhân cho điểm nêm.

EDIT : Đã bỏ ORDER BY, nó dường như hoạt động đúng mà không có nó, ít nhất là trên SQL 2017. Tôi cũng đã bỏ AND y=0điều kiện cập nhật; Tôi đã thử nghiệm cho tất cả các ygiá trị số nguyên , thay đổi x=0để x=1không bao giờ thay đổi điểm số.

EDIT 2 : Đã xóa cột g khỏi bảng d , thay thế nó bằng một IIF()câu lệnh trả về ftrực tiếp (đối với mắt bò) hoặc f*blưu 8 byte. Cũng bỏ không gian sau TOP 1.


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]

Cà vạt phá vỡ ngược chiều kim đồng hồ. (#)là một chức năng tra cứu. Góc cực được sử dụng để lập chỉ mục từ danh sách các số, bắt đầu từ atan2điểm cắt ở 11. Khoảng cách được sử dụng để lập chỉ mục từ danh sách các hàm [const 50, const 25, id, (*3), id, (*2), const 0]và cuối cùng chức năng này được áp dụng cho số chúng ta có trước đây.

Hãy thử trực tuyến!


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

Hãy thử trực tuyến!

Lấy hai không gian tọa độ được phân tách trên STDIN. Tie-break là ngược chiều kim đồng hồ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.