シングルダーツを獲得する


22

前書き

ダーツがダーツボード上のどこに着地するかの座標を指定して、そのダーツのスコアを返すプログラムまたは関数を作成します。ダーツ座標はx,y、ダーツボードの中心からミリメートル精度で測定される2つの整数として与えられます。

ダーツを獲得する方法

ダーツは、円形のボードにダーツを投げてプレイするゲームです。ダーツボードは、20個の同じサイズの「ウェッジ」に分割されています。上部から時計回りに、セクションの値は20,1,18,4,13,6,10,15,2,17,3,19,7,16,8,11,14,9,12になります、5。ダーツがウェッジの黒または白の部分に着地した場合、そのウェッジの外側に示されている値を獲得します。
これはダーツボードの写真です


ただし、ダーツがダーツボードの外側の緑/赤のリングに着地した場合、ヒットしたウェッジの外側に示されているポイントを2倍に獲得します。同様に、内側の緑/赤のリング(2つの白/黒のセクションの間にあるリング)を押すと、ウェッジの外側に示されている数の3倍のスコアを獲得します。ダーツが最も内側の円(赤いブルズアイ)に当たった場合、代わりに50ポイントを獲得し、最後にダーツが2番目に内側の円(ブルズアイの周りの緑のリング)に当たった場合、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)です。この課題のために、ダーツがワイヤーに当たって跳ね返る心配はありません。ダーツが放射状の線の1つで「ワイヤ上」に着地した場合、タイを時計回りまたは反時計回りに分割するかどうかを決定するのは回答者次第です。タイブレーク方向は一貫している必要があります。

注4:ダーツボードは、20セクションの中央がブルズアイの真上にあり、3セクションがブルズアイの真下にある標準的な方法で吊り下げられています。

入力

x,yダーツが着陸した場所の座標を表す2つの整数。ダーツボードの中心を基準にしたミリメートルで測定されます。

出力

与えられた座標に着陸したダーツに与えられるポイントの数を表す単一の整数。

サンプル

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
@シャギー私はそうするためのまともな理由が表示されません。
ジョナサンアラン

5
@Shaggyなぜそうなるべきか説明できますか?個人的には、ダーツが常にダーツボードに当たることが保証されていればそれが大好きですが、挑戦のために、ファンタジーよりも現実に固執するのがベストだと思いました。
-mypetlion

1
テストケースを示唆し:-150,-1そして-150,0その両方与えるべきで11あり、これは極座標におけるシータ収束に-pi及びシータ= + PI間の遷移であるように、いくつかの実施のエッジケースであってもよいです。(私の最初の答えは2番目に失敗しました。)
アーナルド

1
ダンギット、x = y = 0がめちゃくちゃだ!良い挑戦。
BradC

1
気にしないでください、私は2枚目の写真のより良いバージョンで編集しました。
BradC

回答:


19

JavaScript(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)

オンラインでお試しください!

どうやって?

(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バイトを保存しました。


私は誰のは、あなたが使用している場合、あなたを非難するつもりは推測するb33474、赤と緑のために。:-)
アーナルド

けれども@Arnauldフェア十分には、b33あるbb3333のでb22(別名bb3322)に近いあなたの元にありますbe3628
ニール

7

Intel 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を搭載した実際のIBM PC、DOSBox、またはお気に入りのエミュレーターが必要です。

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は同じソース/宛先を使用

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)、147 146バイト

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

改行は読みやすさのためです。イニシャルUPDATEx=y=0、でエラーをスローする問題を処理しますがATN2()、スコアは変更しません。

入力は、既存のテーブルを経由して取得されトン私たちのIOガイドラインごと。を使用しているためTOP 1、このテーブルには1行のみが含まれている必要があります。

基本的に私は3つのテーブルを結合しています:

  • テーブルp:入力テーブルtからのxyは、ポーラーrと、ダーツが落ちたスコアリングウェッジの-11から正の11までの数を表す「ウェッジ」値wに変換されます。「タイブレーカー」は反時計回りです。(少し短くしたを試してみましたが、一貫性のないタイブレーカーを与えました。)ROUND()
  • テーブルs:これは、「ウェッジ」値aをスコアbに変換するルックアップテーブルです。
  • テーブルd:これは、中心からの距離に基づいてスコア計算を返すルックアップテーブルです。eは距離であり、rに結合し、に基づいて単一の行のみを返しますTOP 1。値fは、固定スコア(ブルズアイの場合)またはウェッジスコアの乗数です。

編集:をORDER BY削除しAND y=0ましたが、少なくともSQL 2017ではそれなしで正常に動作するようです。更新条件も削除しました。すべての整数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]

タイは反時計回りに壊れます。(#)ルックアップ関数です。極角はatan2、11のカットオフポイントから開始して、数値のリストからインデックスを作成するために使用されます。距離は、関数のリストからインデックスを作成するために使用され[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で区切られた2つの座標空間を取ります。タイブレークは反時計回りです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.