소개
다트가 다트 판에 놓이는 좌표를 지정하여 해당 다트의 점수를 반환하는 프로그램 또는 함수를 작성하십시오. 다트 좌표는 x,y
다트 판의 중심에서 측정 된 밀리미터 정밀도 로 두 개의 정수로 제공됩니다 .
다트를 득점하는 방법
다트는 원형 보드에 다트를 던지는 게임입니다. 다트 판은 20 개의 동일한 크기의 “쐐기”로 나뉩니다. 상단에서 시작하여 시계 방향으로 이동하면 섹션의 값은 20,1,18,4,13,6,10,15,2,17,3,19,7,16,8,11,14,9,12입니다. , 5. 다트가 쐐기의 검은 색 또는 흰색 부분에 도달하면 해당 쐐기 외부에 표시된 값을 얻습니다.
.
그러나 다트가 다트 판의 바깥 쪽 녹색 / 빨간색 고리에 떨어지면 쐐기 바깥쪽에 표시된 점수가 두 배가됩니다. 마찬가지로 내부 녹색 / 빨간색 링 (두 개의 흰색 / 검정 섹션 사이에있는 링)을 치면 웨지 외부에 표시된 숫자의 세 배가됩니다. 다트가 가장 안쪽 원 (빨간 황소 눈)에 닿으면 대신 50 점을 획득하고 마지막으로 다트가 가장 안쪽에있는 원 (불 눈 주위에 녹색 고리)에 닿으면 25 점을 얻습니다.
다트 판의 중심에서 측정 한 링의 치수는 다음과 같습니다.
Bullseye (50): [0mm-6mm)
25: [6mm-16mm)
Inner Single: [16mm-99mm)
Triple: [99mm-107mm)
Outer Single: [107mm-162mm)
Double: [162mm-170mm)
Miss (0): 170mm+
참고 1 : 제공된 그림은 설명을위한 것으로 크기를 조정하지 않았습니다.
참고 2 : 제공된 측정 값은 근사치이며 실제 다트 보드에는 정확하지 않을 수 있습니다.
참고 3 : 주어진 모든 측정 값은 [inclusive-exclusive)
입니다. 이 도전의 목적을 위해, 우리는 다트가 전선을 치고 튀는 것에 대해 걱정하지 않을 것입니다. 다트가 방사형 선 중 하나를 사용하여 “와이어”에 도달하면 타이를 시계 방향으로 또는 반 시계 방향으로 끊을 지 여부를 결정하는 것은 응답자에게 달려 있습니다. 타이 브레이킹 방향이 일관되고 표시되어야합니다.
참고 4 : 다트 보드는 20 섹션의 중간이 불즈 아이 바로 위에 있고 3 섹션은 불즈 아이 바로 아래에 표준 방식으로 걸려 있습니다.
입력
x,y
다트 판의 중심을 기준으로 밀리미터 단위로 측정 된 다트의 위치 좌표를 나타내는 두 개의 정수 입니다.
산출
주어진 좌표에 도달 한 다트에 부여 될 포인트 수에 대한 단일 정수.
견본
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
채점
code-golf . 소스 코드에서 가장 적은 바이트가 이깁니다.
표준 허점은 금지되어 있습니다.
답변
자바 스크립트 (ES7), 137 바이트
카레 구문에서 좌표를 가져옵니다 (x)(y)
. 반 시계 방향 타이 브레이크를 사용합니다.
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)
방법?
그래픽 출력
다음 ES6 코드 스 니펫은 골프 코드와 동일한 논리를 사용하여 다트 보드를 그립니다.
답변
자바 스크립트 (ES6) + SVG (HTML5) 53 + 523 51 + 519 507 = 576 570 558 바이트
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`)>
입력은 마우스 클릭,을 통한 출력 alert
입니다. 편집 : @Arnauld가 제안한 것처럼 약간 더 가까운 색상을 사용하여 12 바이트를 절약했습니다.
답변
인텔 8086/8087 어셈블리, 180 144 142 138 바이트
이것은 모든 삼각 및 부동 소수점 산술에 8087 수학 코 프로세서를 사용합니다. 모든 계산은 80 비트 부동 소수점 정밀도의 하드웨어에서 수행됩니다.
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
MASM MACRO (기본적으로 함수)로 작성되며 X와 Y를 좌표로 사용하고 계산 된 점수를 AX로 반환합니다. 넥타이는 시계 방향으로 끊어집니다.
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
PC DOS 테스트 프로그램 예. 여기에서 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 ?
산출
위의 테스트 프로그램 사용 예 . 8087, DOSBox 또는 선호하는 에뮬레이터가있는 실제 IBM PC가 필요합니다.
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
* 편집 :
- 잘림 반올림 문과 10.5 상수를 제거하여 -36 바이트 타이는 이제 시계 방향으로 고장났습니다.
- 더 이상 필요없는 FRNDINT를 제거하여 -2 바이트
- -4 바이트, FMUL은 동일한 소스 / 대상을 사용합니다
답변
젤리 , 56 바이트
æA/Æ°_9:18ị“!@umÞẓẓS’Œ?¤
ḅıA<“©Ñckɱȥ‘TṂị“2ı¢¤¢£¡‘¹×>3$?Ç
[x,y]
점수를 산출 하는 목록으로 쌍을 허용하는 모나드 링크 .
시계 방향 타이 브레이킹을 사용합니다.
온라인으로 사용해보십시오! 또는 시험 스위트를 참조하십시오
방법?
æ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)
답변
TI 기본 (TI-84 Plus CE), 147146 바이트
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
별도의 줄에 X와 Y를 묻습니다.
시계 반대 방향으로 타이 브레이크.
TI-Basic은 토큰 화 된 언어입니다 . 여기에 사용 된 모든 토큰은 1 바이트입니다.
설명:
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
TI- 기본 부울 비교에 더하고 점 값을 곱하여 0 또는 1을 반환한다는 사실을 활용합니다.
답변
T-SQL, 3923774366 바이트
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
줄 바꿈은 가독성을위한 것입니다. 이니셜 UPDATE
은 x=y=0
으로 오류를 발생 시키는 문제를 처리 ATN2()
하지만 점수는 변경하지 않습니다.
입력은 기존의 테이블을 통해 촬영 t , 우리의 IO 지침에 따라 . 를 사용하기 TOP 1
때문에이 테이블은 단일 행만 포함해야합니다.
기본적으로 3 개의 테이블을 결합합니다.
- 표 p : 입력 테이블 t 의 x 와 y 는 극성 r 로 변환되고 다트가 떨어진 스코어링 웨지에 대해 -11에서 양수 11까지의 숫자를 나타내는 “쐐기”값 w 로 변환됩니다. “타이 브레이커”는 시계 반대 방향입니다. ( 약간 더 짧았지만 일관성이없는 타이 브레이커를 시도 했습니다.)
ROUND()
- Table s : “쐐기”값 a 를 점수 b 로 변환하는 조회 테이블 입니다.
- 표 d : 중심으로부터의 거리를 기준으로 점수 계산을 반환하는 조회 테이블입니다. e 는 거리이며 r에 연결되며를 기준으로 단일 행만 반환합니다
TOP 1
. 값 f 는 고정 점수 (과녁의 경우) 또는 웨지 점수의 배수입니다.
편집 :을 삭제 ORDER BY
했습니다. 적어도 SQL 2017에서는 제대로 작동하지 않는 것 같습니다. 또한 AND y=0
업데이트 조건을 삭제했습니다 . 점수를 변경하지 않도록 y
변경 x=0
하여 모든 정수 값을 테스트했습니다 x=1
.
편집 2 : 테이블 d 에서 열 g 를 제거 하고 직접 (불즈 아이를 위해) 반환 하거나 8 바이트를 저장 하는 문으로 대체했습니다 . 또한 이후 공간을 제거했습니다 .IIF()
f
f*b
TOP 1
답변
하스켈 , 198 바이트
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]
타이는 반 시계 방향으로 끊어집니다. (#)
조회 기능입니다. 극각은 atan2
11의 컷오프 지점에서 시작하여 숫자 목록에서 색인화하는 데 사용됩니다 . 거리는 기능 목록에서 색인화하는 데 사용 [const 50, const 25, id, (*3), id, (*2), const 0]
되며 마지막으로이 함수는 이전에 얻은 숫자에 적용됩니다.