Marquez une seule fléchette

22

introduction

Écrivez un programme ou une fonction qui, étant donné les coordonnées de l'endroit où une fléchette atterrit sur une cible, renvoie le score de cette cible. Les coordonnées des fléchettes sont données sous forme de deux nombres entiers, x,ymesurés à partir du centre du jeu de fléchettes, avec une précision millimétrique.

Comment marquer une fléchette

Fléchettes est un jeu joué en lançant une fléchette sur un plateau circulaire. Le jeu de fléchettes est divisé en 20 "coins" de taille égale. En partant du haut et dans le sens horaire, les sections ont des valeurs de 20,1,18,4,13,6,10,15,2,17,3,19,7,16,8,11,14,9,12 , 5. Si votre fléchette atterrit dans les parties noires ou blanches de l'un des coins, vous marquez la valeur indiquée à l'extérieur de ce coin.
voici une photo d'un jeu de fléchettes.


Cependant, si votre fléchette atterrit dans l'anneau extérieur vert / rouge du jeu de fléchettes, vous marquez le double des points indiqués à l'extérieur du coin que vous avez touché. De même, en frappant l'anneau intérieur vert / rouge (celui entre les deux sections blanches / noires), vous marquez le triple du nombre indiqué à l'extérieur du coin. Si votre fléchette frappe le cercle le plus à l'intérieur (l'oeil de boeuf rouge), vous marquez à la place 50 points et enfin, si votre fléchette frappe le deuxième cercle le plus à l'intérieur (l'anneau vert autour de l'oeil de boeuf), vous marquez 25 points.

Les dimensions des anneaux, mesurées à partir du centre du jeu de fléchettes, sont les suivantes:

l'image n'est pas à l'échelle


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

Remarque 1: les images fournies sont fournies à titre d'illustration uniquement et ne sont pas à l'échelle.

Remarque 2: les mesures fournies sont approximatives et peuvent ne pas être exactes pour un véritable jeu de fléchettes.

Note 3: Toutes les mesures données sont [inclusive-exclusive). Aux fins de ce défi, nous n'allons pas nous inquiéter des fléchettes frappant le fil et rebondissant. Si la fléchette atterrit "sur le fil" avec l'une des lignes radiales, il appartient au répondeur de décider de rompre le lien dans le sens horaire ou antihoraire. Le sens de rupture des liens doit être cohérent et indiqué.

Remarque 4: Le jeu de fléchettes est suspendu de manière standard, le milieu de la section 20 étant directement au-dessus de la bulle et la section 3 directement en dessous de la bulle.

Contribution

Deux entiers représentant les x,ycoordonnées de l'endroit où la fléchette a atterri, mesurées en millimètres, par rapport au centre de la cible.

Sortie

Un seul entier, pour le nombre de points qui seraient attribués à une fléchette qui a atterri aux coordonnées données.

Échantillon

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

Notation

. Le moins d'octets dans votre code source gagne.

Failles standard interdites .

mypetlion
la source
1
@Shaggy Je ne vois aucune raison décente de le faire.
Jonathan Allan
5
@Shaggy Pouvez-vous expliquer pourquoi cela devrait être le cas? Personnellement, j'adorerais que mes fléchettes soient toujours garanties de toucher le jeu de fléchettes, mais pour le défi, j'ai pensé qu'il valait mieux s'en tenir à la réalité plutôt qu'à la fantaisie.
mypetlion
1
Cas de test suggérés: -150,-1et -150,0qui devraient à la fois donner 11et peuvent être un cas de bord sur certaines implémentations, car il s'agit de la transition entre thêta convergeant vers -pi et thêta = + pi en coordonnées polaires. (Ma réponse initiale a échoué le 2e.)
Arnauld
1
Dangit, x = y = 0 me dérange complètement !! Bon défi.
BradC
1
J'espère que cela ne vous dérange pas, j'ai édité une meilleure version de la deuxième photo.
BradC

Réponses:

19

JavaScript (ES7), 137 octets

Prend les coordonnées dans la syntaxe de curry (x)(y). Utilise le tie-break dans le sens antihoraire.

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)

Essayez-le en ligne!

Comment?

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

Sortie graphique

L'extrait de code ES6 suivant dessine le jeu de fléchettes en utilisant la même logique que dans le code golfé.

Arnauld
la source
8

JavaScript (ES6) + SVG (HTML5), 53 + 523 51 + 519 507 = 576 570 558 octets

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

L'entrée se fait via un clic de souris, la sortie via alert. Edit: enregistré 12 octets en utilisant des couleurs légèrement plus approximatives comme suggéré par @Arnauld.

Neil
la source
Je suppose que personne ne vous en voudra si vous utilisez b33et 474pour le rouge et le vert. :-)
Arnauld
Assez @Arnauld juste, bien que b33est bb3333si b22(aka bb3322) est plus proche de l' original be3628.
Neil
7

Assemblage Intel 8086/8087, 180 144 142 138 octets

Celui-ci utilise le coprocesseur mathématique 8087 pour l'ensemble de l'arithmétique trigonométrique et virgule flottante. Tous les calculs sont effectués en matériel avec une précision à virgule flottante de 80 bits.

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

Écrit en tant que MACRO MASM (essentiellement une fonction), prend X et Y comme coordonnées et renvoie le score calculé dans AX. La cravate est brisée dans le sens des aiguilles d'une montre.

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

Un exemple de programme de test pour PC DOS. Téléchargez-le ici 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  ?

Sortie

Exemple d'utilisation du programme de test ci-dessus . PC IBM réel avec 8087, DOSBox ou votre émulateur préféré requis.

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

* Modifications:

  • -36 octets en supprimant l'instruction d'arrondi tronqué et la constante 10,5. Cravate maintenant brisée dans le sens des aiguilles d'une montre.
  • -2 octets en supprimant plus nécessaire FRNDINT
  • -4 octets, FMUL utilise la même source / destination
640 Ko
la source
6

Gelée , 56 octets

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

Un lien monadique acceptant la paire comme une liste [x,y]qui donne le score.
Utilise le bris d'égalité dans le sens horaire.

Essayez-le en ligne! Ou consultez la suite de tests

NB une version dyadique fait aussi 56 octets

Comment?

æ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
la source
4

TI-Basic (TI-84 Plus CE), 147146 octets

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

Invite X et Y sur des lignes distinctes.

Cravates dans le sens antihoraire.

TI-Basic est un langage à jetons ; tous les jetons utilisés ici sont d'un octet.

Explication:

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

Utilise le fait que les comparaisons booléennes TI-Basic retournent 0 ou 1 en les additionnant et en les multipliant par des valeurs en points.

pizzapants184
la source
3

T-SQL, 392 374 366 octets

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

Les sauts de ligne sont pour la lisibilité. L'initiale UPDATEs'occupe du x=y=0problème qui, sinon, entraînerait une erreur ATN2(), mais ne change pas le score.

L'entrée est prise via la table t préexistante , selon nos directives IO . En raison de l'utilisation TOP 1, ce tableau ne doit contenir qu'une seule ligne.

Fondamentalement, je rejoins 3 tables:

  • Tableau p : Les x et y du tableau d'entrée t sont convertis en polaires r et une valeur de «coin» w représentant un nombre de -11 à 11 positif, pour le coin de notation dans lequel la fléchette est tombée. "Tie breaker" est dans le sens antihoraire. (J'ai essayé ROUND(), ce qui était légèrement plus court, mais cela a donné un bris d'égalité incohérent.)
  • Tableau s : Il s'agit d'un tableau de recherche pour convertir une valeur de «coin» a en un score b .
  • Tableau d : Il s'agit d'un tableau de recherche qui renvoie le calcul du score en fonction de la distance du centre. e est la distance et rejoint r et ne renvoie qu'une seule ligne basée sur le TOP 1. La valeur f est soit un score fixe (pour un oeil de boeuf) ou un multiplicateur pour le score de coin.

EDIT : Supprimé le ORDER BY, il semble fonctionner correctement sans lui, au moins sur SQL 2017. J'ai également supprimé la AND y=0condition de mise à jour; J'ai testé toutes les yvaleurs entières , en changeant x=0pour x=1ne jamais changer le score.

EDIT 2 : Suppression de la colonne g du tableau d , remplacement de celle-ci par une IIF()instruction qui renvoie soit fdirectement (pour un œil de boeuf), soit f*béconomise 8 octets. A également supprimé l'espace après TOP 1.

BradC
la source
2

Haskell , 198 octets

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]

Le lien se brise dans le sens antihoraire. (#)est une fonction de recherche. L'angle polaire est utilisé pour indexer à partir de la liste des nombres, en commençant au atan2point de coupure à 11. La distance est utilisée pour indexer à partir de la liste des fonctions [const 50, const 25, id, (*3), id, (*2), const 0]et enfin cette fonction est appliquée au nombre que nous avons précédemment obtenu.

Essayez-le en ligne!

Angs
la source
1

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

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

Essayez-le en ligne!

Prend l'espace des deux coordonnées séparées sur STDIN. Le bris d'égalité se fait dans le sens inverse des aiguilles d'une montre.

Xcali
la source