Create your own mechanical dartboard that gives back your score based on the coordinates of your dart.

Task:

Use the scoring rules for a standard dartboard:


Finish method:

```python
def get_score(x,y):
```

The coordinates are `(x, y)` are always relative to the center of the board (0, 0). The unit is millimeters. If you throw your dart 5 centimeters to the left and 3 centimeters below, it is written as:

```python
score = get_score(-50, -30)
```

Possible scores are:Outside of the board: `"X"`Bull's eye: `"DB"`Bull: `"SB"`A single number, example: `"10"`A triple number: `"T10"`A double number: `"D10"`
A throw that ends exactly on the border of two sections results in a bounce out. You can ignore this because all the given coordinates of the tests are within the sections.
The diameters of the circles on the dartboard are:Bull's eye: `12.70 mm`Bull: `31.8 mm`Triple ring inner circle: `198 mm`Triple ring outer circle: `214 mm`Double ring inner circle: `324 mm`Double ring outer circle: `340 mm`

If you liked this kata, you can continue with: Let's Play Darts: Beat The Power!

Difficulty: introductory

Starter code:

def get_score(x,y):
	

Solutions:
from math import atan2, degrees

def get_score(x,y):
    r, a = (x*x + y*y)**0.5, degrees(atan2(y, x)) + 9
    t = str([6,13,4,18,1,20,5,12,9,14,11,8,16,7,19,3,17,2,15,10][int(a + 360 if a < 0 else a)//18])
    for l, s in [(6.35, 'DB'),(15.9,'SB'),(99,t),(107,'T'+t),(162,t),(170,'D'+t)]:
        if r <= l: return s
    
    return 'X'    

import cmath

# Dartboard sectors, beginning at 0 angle (i.e. middle of 6), continuing CCW:
_SECTORS = [6, 13, 4, 18, 1, 20, 5, 12, 9, 14, 11, 8, 16, 7, 19, 3, 17, 2, 15, 10]

# Diameters in increasing order, and resulting format string for score:
_RESULTS = [(12.7, 'DB'), (31.8, 'SB'), (198., '{}'), (214., 'T{}'), (324., '{}'), (340., 'D{}')] 

# 1/2 the angle of a single number on the board (since sectors don't start on 0 angle)
_SLICE = math.pi / 20.

def get_score(x,y):
    point = complex(x, y)
    distance, angle = cmath.polar(point)
    
    # Negative angles work by indexing the sector list with a negative index!
    # The check against "< _SLICE" takes care of the wraparound at '6':
    i = 0 if abs(angle) < _SLICE else int(round(angle / _SLICE / 2))
    
    sector = _SECTORS[i]
    
    # Take the first format we reach in distance, and default to 'X' if we go beyond the board:
    result = next((fmt for diameter, fmt in _RESULTS if distance < diameter / 2.), 'X')
    return result.format(sector)

from cmath import pi, polar
SECTIONS = [6,13,4,18,1,20,5,12,9,14,11,8,16,7,19,3,17,2,15,10]
RINGS = [12.7, 31.8, 198, 214, 324, 340]
SCORES = 'DB SB {} T{} {} D{} X'.split()

def get_score(x, y):
    r, phi = polar(x + 1j * y)
    r, phi = 2 * r, phi + pi / 20
    section = SECTIONS[int(10 * phi // pi)]
    for d, f in zip(RINGS, SCORES):
        if r < d:
            return f.format(section)
    return SCORES[-1]

from math import atan2, degrees

def get_score(x, y):
    scores = [8, 16, 7, 19, 3, 17, 2, 15, 10, 6,
              13, 4, 18, 1, 20, 5, 12, 9, 14, 11]
    
    distance = (x*x + y*y) ** 0.5
    angle = degrees(atan2(y, x))
    mod = ''
    
    if distance > 340 / 2:
        return 'X'         # outside
    elif distance < 12.7 / 2:
        return 'DB'        # bull's eye
    elif distance < 31.8 / 2:
        return 'SB'        # bull
    elif 198 / 2 < distance < 214 / 2:
        mod = 'T'          # triple
    elif 324 / 2 < distance < 340 / 2:
        mod = 'D'          # double
    
    number = str( scores[int((angle + 180 + 9) / 18) - 1] )
    
    return mod + number

import math
def get_score(x,y):
    P = '6 13 4 18 1 20 5 12 9 14 11 8 16 7 19 3 17 2 15 10 6'
    C = [(0,'DB'),(12.7,'SB'),(31.8,''),(198,'T'),(214,''),(324,'D'),(340,'X')]
    r, phi = math.sqrt(x*x+y*y), 180*math.atan2(y, x)/math.pi
    phi += [0,360][phi < 0]
    p = [p for i, p in enumerate(P.split()) if i*18-9 < phi][-1]
    c = [c for c in C if c[0]/2 < r][-1][1]
    return c + ['',p][c in ('','D','T')]

import math

STR_MODIFIERS, STR_OUT = "TD", "X"
PI = math.pi
OUT_OF_BORDER, ANGLE_OFFSET = 340.0/2, 2*PI/40
CIRCLES = {(0,12.70): "DB", (12.70,31.8):"SB", (198,214):"T", (324,340):"D"}
PARTS = [6, 13, 4, 18, 1, 20, 5, 12, 9, 14, 11, 8, 16, 7, 19, 3, 17, 2, 15, 10]

def get_score(x,y):
    ans, d = "", (x**2+y**2)**.5
    theta = (math.atan(y/float(x)) + PI*(x<0) + ANGLE_OFFSET + 2*PI) % (2*PI)
    
    if d > OUT_OF_BORDER: return STR_OUT
    for k,v in CIRCLES.items():
        if k[0]/2.0 < d < k[1]/2.0:
            if v not in STR_MODIFIERS: return v
            ans += v
            break
    
    return ans + str(PARTS[int(theta/(2*PI/20))])

from math import atan2, hypot, pi

ZONES = ["6", "13", "4", "18", "1", "20", "5", "12", "9", "14", "11", "8", "16", "7", "19", "3", "17", "2", "15", "10"]

def get_score(x,y):
    dist = hypot(x, y)
    if dist > 170: return "X"
    if dist < 6.35: return "DB"
    if dist < 15.9: return "SB"
    angle = (atan2(y, x) + (pi / 20)) % (2 * pi)
    zone = ZONES[int((angle / pi) * 10)]
    if 99 < dist < 107: return "T" + zone
    if 162 < dist < 170: return "D" + zone
    return zone

import math

PI = math.pi

def build_cutoffs():
    angle = PI/10
    start = PI/20
    cutoffs = [start]
    for i in range(1,20):
        cutoffs.append(start + angle)
        start+=angle
    return cutoffs

hitvals = [6, 13, 4, 18, 1, 20, 5, 12, 9, 14, 11, 8, 16, 7, 19, 3, 17, 2, 15, 10]
num_cutoffs = build_cutoffs()

def calc_angle(x,y):
    oa = y/x
    taninv = math.atan(abs(oa))
    if oa > 0:
        radang = PI + taninv if y<0 else taninv
    else:
        radang = PI - taninv if x < 0 else 2*PI - taninv
    return radang

def get_score(x,y):
    ang = calc_angle(x,y)
    for i, c in enumerate(num_cutoffs):
        if ang < c:
            numval = hitvals[i]
            break
    else:
        numval = 6

    dist = math.sqrt(x**2 + y**2)
    if dist > 170:
        return 'X'
    if dist > 162:
        return f'D{numval}'
    if dist > 99 and dist < 107:
        return f'T{numval}'
    if dist > 6.35 and dist < 15.9:
        return 'SB'
    if dist < 6.35:
        return 'DB'
    return f'{numval}'

from math import hypot, atan2, degrees


def get_score(x,y):
    r = hypot(x,y)
    fi = degrees(atan2(y,x))
    dictio = {-9 < fi < 9: "6", 9 < fi < 27: "13", 27 < fi < 45: "4", 45 < fi < 63: "18", 63 < fi < 81: "1",
              81 < fi < 99: "20", 99 < fi < 117: "5", 117 < fi < 135: "12", 135 < fi < 153: "9", 153 < fi < 171: "14",
              -27 < fi < -9: "10", -45 < fi < -27: "15", -63 < fi < -45: "2", -81 < fi < -63: "17",
              -99 < fi < -81: "3", -117 < fi < -99: "19", -135 < fi < -117: "7", -153 < fi < -135: "16", -171 < fi < -153: "8",
              -180 < fi < -171: "11", 171 < fi < 180: "11"}
    
    if r > 170:
        return "X"
        
    if 0 <= r <= 6.35:
        return "DB"
    
    if 6.35 < r <= 15.9:
        return "SB"
    
    number = dictio[True]
            
    return "T" * (99 < r < 107) + "D" * (162 < r < 170) + number

from math import atan, pi

def get_score(x,y):
    d = (x * x + y * y) ** .5
    if d < 6.35: return 'DB'
    if d < 15.9: return 'SB'
    if 170 < d: return 'X'
    prefix = 'D' if 162 < d else 'T' if 99 < d < 107 else ''
    slice = round((atan(y/x) / pi + (x < 0)) * 10) % 20
    return prefix + '6 13 4 18 1 20 5 12 9 14 11 8 16 7 19 3 17 2 15 10'.split()[slice]