得分单个飞镖


22

介绍

编写一个程序或函数,给定飞镖在飞镖上降落的坐标,并返回该飞镖的得分。飞镖坐标为两个整数,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

计分

。源代码中的字节数最少。

禁止标准漏洞


1
@Shaggy我看不到这样做的任何正当理由。
乔纳森·艾伦,

5
@Shaggy您能解释为什么会这样吗?就个人而言,如果我的飞镖能始终保证击中飞镖板,我会喜欢的,但是为了挑战,我认为最好坚持现实而不是幻想。
mypetlion

1
建议测试用例:-150,-1-150,0其中应该都给予11,并且可以在一些实施方式中的边缘的情况下,因为这是THETA会聚到-pi和θ= +极坐标PI之间的过渡。(我的最初回答在第二个失败。)
Arnauld

1
Dangit,x = y = 0完全把我搞砸了!!好挑战。
BradC

1
希望您不要介意,我编辑了第二张照片的更好版本。
BradC

Answers:


19

JavaScript(ES7),137个字节

以currying语法获取坐标(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)

在线尝试!

怎么样?

(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θπθ+π

图形输出

以下ES6代码片段使用与高尔夫球代码相同的逻辑绘制飞镖。


8

的JavaScript(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个字节。


我想没有人会如果你使用怪你b33,并474为红色和绿色。:-)
Arnauld

@Arnauld很公平,尽管b33bb3333这样b22(又名bb3322)更接近原始的be3628
尼尔

7

英特尔8086/8087组件 180 144 142 138字节

这将对所有trig和浮点运算使用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

*编辑:

  • 通过删除truncate-rounding语句和10.5常量,可得到-36字节。领带现在按顺时针方向断开。
  • 通过删除不再需要的FRNDINT -2字节
  • -4个字节,FMUL使用相同的源/目标

6

果冻,56 字节

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

接受一对的单子链接作为[x,y]产生分数的列表。
使用顺时针抢七。

在线尝试!或查看测试套件

注意,二进位版本也是56个字节

怎么样?

æ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),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是一种标记化语言;这里使用的所有令牌都是一个字节。

说明:

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-Basic布尔比较通过将它们相加并乘以点值来返回0或1的事实。


3

T-SQL,392374366字节

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(),但不会改变得分。

根据我们的IO准则,通过预先存在的表t进行输入。由于使用,此表应仅包含一行。TOP 1

基本上我要加入3个表:

  • 表p:将输入表t中的xy转换为极数r,并将“ 飞镖”值w表示从-11到正11的数字,这是飞镖落入的得分楔子。“平分机”是逆时针方向。(我尝试过,它稍短一些,但它给断线器带来了不一致。)ROUND()
  • 表s:这是一个将“楔形”值a转换为得分b的查找表。
  • 表d:这是一个查找表,根据距中心的距离返回分数计算。e是距离,并连接到r,并且仅基于返回单行TOP 1。值f是固定分数(对靶心)或楔形分数乘数。

编辑ORDER BY删除了,但似乎没有它,也可以正常工作,至少在SQL 2017上也是如此AND y=0。我测试了所有整y数值,更改x=0x=1从不更改得分。

编辑2:从表d中删除了列g,将其替换为直接返回(用于靶心)或保存8个字节的语句。之后也删除了空格。IIF()ff*bTOP 1


2

Haskell,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]

领带逆时针方向断裂。(#)是查找功能。极角用于从列表中的索引开始,从atan211 的截止点开始。距离用于从函数列表中进行索引[const 50, const 25, id, (*3), id, (*2), const 0],最后将此函数应用于我们先前获得的数字。

在线尝试!


1

Perl -MMath::Trig':pi' -MMath::Trig':radial' -apl 5、166字节

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

在线尝试!

取STDIN上分隔的两个坐标空间。抢奖是逆时针的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.