Erziele einen einzelnen Pfeil

22

Einführung

Schreiben Sie ein Programm oder eine Funktion, die anhand der Koordinaten, in denen ein Pfeil auf einer Dartscheibe landet, die Punktzahl dieses Pfeils zurückgibt. Dartkoordinaten werden als zwei Ganzzahlen angegeben, x,ydie von der Mitte der Dartscheibe aus millimetergenau gemessen werden.

Wie man einen Pfeil schießt

Dart ist ein Spiel, bei dem ein Pfeil auf ein kreisförmiges Brett geworfen wird. Die Dartscheibe ist in 20 gleich große "Wedges" unterteilt. Ausgehend von oben und im Uhrzeigersinn haben die Abschnitte Werte von 20,1,18,4,13,6,10,15,2,17,3,19,7,16,8,11,14,9,12 , 5. Wenn Ihr Pfeil in den schwarzen oder weißen Teilen eines der Keile landet, erhalten Sie den Wert, der auf der Außenseite dieses Keils angegeben ist.
Hier ist ein Bild von einer Dartscheibe.


Wenn Ihr Pfeil jedoch im äußeren grün / roten Ring der Dartscheibe landet, erhalten Sie doppelt so viele Punkte wie auf der Außenseite des von Ihnen getroffenen Keils angegeben. Wenn Sie auf den inneren grün / roten Ring (den Ring zwischen den beiden weiß / schwarzen Abschnitten) treffen, erhalten Sie die dreifache Punktzahl, die auf der Außenseite des Keils angegeben ist. Trifft Ihr Pfeil auf den innersten Kreis (das rote Bullauge), erhalten Sie stattdessen 50 Punkte. Trifft Ihr Pfeil auf den zweitinnersten Kreis (den grünen Ring um das Bullauge), erhalten Sie 25 Punkte.

Die Abmessungen der Ringe, gemessen von der Mitte der Dartscheibe, sind wie folgt:

Bild nicht maßstabsgetreu


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

Hinweis 1: Die angegebenen Bilder dienen nur zu Illustrationszwecken und sind nicht maßstabsgetreu.

Hinweis 2: Die angegebenen Maße sind ungefähre Werte und können von einer echten Dartscheibe abweichen.

Anmerkung 3: Alle angegebenen Maße sind [inclusive-exclusive). Für die Zwecke dieser Herausforderung brauchen wir uns keine Sorgen zu machen, dass Pfeile den Draht treffen und abprallen. Wenn der Pfeil mit einer der radialen Linien "auf dem Draht" landet, muss der Antwortende entscheiden, ob die Verbindung im oder gegen den Uhrzeigersinn abgebrochen wird. Die Biegerichtung muss übereinstimmen und angegeben werden.

Anmerkung 4: Die Dartscheibe wird wie üblich aufgehängt, wobei die Mitte des Abschnitts 20 direkt über dem Bullseye und der Abschnitt 3 direkt unter dem Bullseye liegt.

Eingang

Zwei Ganzzahlen, die die x,yKoordinaten der Landung des Pfeils in Millimetern relativ zur Mitte der Dartscheibe darstellen.

Ausgabe

Eine einzelne Ganzzahl für die Anzahl der Punkte, die für einen Pfeil vergeben werden, der an den angegebenen Koordinaten gelandet ist.

Probe

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

Wertung

. Die wenigsten Bytes in Ihrem Quellcode gewinnen.

Standardlücken verboten .

mypetlion
quelle
1
@ Shaggy Ich sehe keinen Grund dafür.
Jonathan Allan
5
@Shaggy Kannst du erklären, warum das so sein sollte? Persönlich würde ich es lieben, wenn meine Darts immer garantiert auf der Dartscheibe landen würden, aber um der Herausforderung willen hielt ich es für das Beste, sich an die Realität zu halten und nicht an die Fantasie.
Mypetlion
1
Vorgeschlagene Testfälle: -150,-1und -150,0die 11bei einigen Implementierungen sowohl einen Randfall ergeben als auch möglicherweise einen Randfall darstellen, da dies der Übergang zwischen Theta-Konvergenz zu -pi und Theta = + pi in Polarkoordinaten ist. (Meine erste Antwort schlug am 2. fehl.)
Arnauld
1
Verdammt, x = y = 0 bringt mich total durcheinander !! Gute Herausforderung.
BradC
1
Ich hoffe, es macht dir nichts aus, ich habe das zweite Bild in einer besseren Version bearbeitet.
BradC

Antworten:

19

JavaScript (ES7), 137 Byte

Übernimmt die Koordinaten in Currying-Syntax (x)(y). Wird gegen den Uhrzeigersinn verwendet.

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)

Probieren Sie es online!

Wie?

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

Grafische Ausgabe

Das folgende ES6-Code-Snippet zeichnet die Dartscheibe nach der gleichen Logik wie im Golf-Code.

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

Die Eingabe erfolgt per Mausklick, die Ausgabe per alert. Bearbeiten: 12 Bytes mit etwas mehr ungefähren Farben gespeichert, wie von @Arnauld vorgeschlagen.

Neil
quelle
Ich denke, niemand wird dir die Schuld geben, wenn du b33und 474für Rot und Grün verwendest. :-)
Arnauld
@Arnauld Fair genug, obwohl b33das bb3333ja b22(aka bb3322) näher an deinem Original liegt be3628.
Neil
7

Intel 8086/8087 Assembly, 180 144 142 138 Bytes

Dabei wird der 8087-Mathe-Coprozessor für alle Trigger- und Gleitkomma-Arithmetik verwendet. Alle Berechnungen werden in Hardware mit einer Gleitkomma-Genauigkeit von 80 Bit ausgeführt.

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

Geschrieben als MASM MACRO (im Grunde eine Funktion), nimmt X und Y als Koordinaten und gibt die berechnete Punktzahl in AX zurück. Die Krawatte ist im Uhrzeigersinn gebrochen.

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

Ein Beispiel-Testprogramm für PC-DOS. Laden Sie es hier herunter 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  ?

Ausgabe

Anwendungsbeispiel des obigen Testprogramms . Tatsächlicher IBM PC mit 8087, DOSBox oder Ihrem Lieblingsemulator erforderlich.

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

* Bearbeitungen:

  • -36 Bytes durch Entfernen der Truncate-Rounding-Anweisung und der 10.5-Konstante. Binden Sie jetzt im Uhrzeigersinn gebrochen.
  • -2 Bytes durch Entfernen von nicht mehr benötigtem FRNDINT
  • -4 Bytes, FMUL verwenden dieselbe Quelle / dasselbe Ziel
640 KB
quelle
6

Jelly , 56 Bytes

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

Ein monadischer Link, der das Paar als Liste akzeptiert, aus der [x,y]die Punktzahl hervorgeht.
Wird im Uhrzeigersinn zum Brechen verwendet.

Probieren Sie es online! Oder sehen Sie sich die Testsuite an

NB eine dyadische Version ist auch 56 Bytes

Wie?

æ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
quelle
4

TI-Basic (TI-84 Plus CE), 147 bis 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

Fordert zur Eingabe von X und Y in separaten Zeilen auf.

Gleichstand gegen den Uhrzeigersinn.

TI-Basic ist eine Token-Sprache . Alle hier verwendeten Token sind ein Byte.

Erläuterung:

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

Nutzt die Tatsache, dass boolesche TI-Basic-Vergleiche 0 oder 1 zurückgeben, indem sie addiert und mit Punktwerten multipliziert werden.

Pizzapants184
quelle
3

T-SQL, 392 374 366 Bytes

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

Zeilenumbrüche dienen der Lesbarkeit. Die Initialisierung UPDATEkümmert sich um das x=y=0Problem, das andernfalls einen Fehler verursachen würde ATN2(), ändert aber nicht die Punktzahl.

Die Eingabe erfolgt über bereits vorhandene Tabelle entnommen t , gemäß unseren IO - Richtlinien . Aufgrund der Verwendung TOP 1sollte diese Tabelle nur eine einzelne Zeile enthalten.

Grundsätzlich gehe ich zu 3 Tischen:

  • Tabelle p : Das x und y aus der Eingabetabelle t werden in polar r und einen "Keil" -Wert w umgewandelt, der eine Zahl von -11 bis positiv 11 darstellt, für den Wertungskeil, in den der Pfeil gefallen ist. "Tie Breaker" ist gegen den Uhrzeigersinn. (Ich habe versucht ROUND(), was etwas kürzer war, aber es gab einen inkonsistenten Tie Breaker.)
  • Tabelle s : Dies ist eine Nachschlagetabelle, um einen "Keil" -Wert a in eine Punktzahl b umzuwandeln .
  • Tabelle d : Dies ist eine Nachschlagetabelle, die die Punktzahlberechnung basierend auf dem Abstand vom Zentrum zurückgibt. e ist die Entfernung und verbindet sich mit r und gibt nur eine einzelne Zeile basierend auf dem zurück TOP 1. Der Wert f ist entweder eine feste Punktzahl (für ein Volltreffer) oder ein Multiplikator für die Keilpunktzahl.

BEARBEITEN : Fiel die ORDER BY, es scheint richtig zu funktionieren, zumindest in SQL 2017. Ich habe auch AND y=0die Update-Bedingung fallen gelassen ; Ich habe auf alle ganzzahligen yWerte getestet und die Punktzahl so geändert , dass x=0sie sich x=1nie ändert.

BEARBEITEN 2 : Spalte g aus Tabelle d entfernt , durch eine IIF()Anweisung ersetzt, die entweder fdirekt (für ein Volltreffer) zurückgibt oder f*b8 Byte gespeichert hat. Auch das Leerzeichen nach entfernt TOP 1.

BradC
quelle
2

Haskell , 198 Bytes

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]

Krawattenbruch gegen den Uhrzeigersinn. (#)ist eine Suchfunktion. Der Polarwinkel wird verwendet, um aus der Liste der Zahlen zu indexieren, beginnend mit dem atan2Grenzpunkt bei 11. Der Abstand wird verwendet, um aus der Liste der Funktionen zu indexieren, [const 50, const 25, id, (*3), id, (*2), const 0]und zuletzt wird diese Funktion auf die zuvor erhaltene Zahl angewendet.

Probieren Sie es online!

Angs
quelle
1

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

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

Probieren Sie es online!

Nimmt den auf STDIN getrennten Raum mit zwei Koordinaten. Das Brechen erfolgt gegen den Uhrzeigersinn.

Xcali
quelle