Use Structural Pattern Matching ('Match-Case')

Darts
Darts in Python
from math import hypot, ceil


def score(x, y):
    throw = ceil(hypot(x, y))
    
    match throw:
        case 0 | 1: return 10
        case 2 | 3 | 4 | 5: return 5
        case 6 | 7 | 8 | 9 | 10: return 1
        case _: return 0

#OR#

def score(x, y):
    match ceil(hypot(x, y)):
        case 0 | 1: return 10
        case 2 | 3 | 4 | 5: return 5
        case 6 | 7 | 8 | 9 | 10: return 1
        case _: return 0

This approach uses Python 3.10's structural pattern matching with return values on the same line as case. Because the match is numeric, each case explicitly lists allowed values using the | (OR) operator. A fallthrough case (_) is used if the dart throw is greater than 10 (the outer circle radius of the target). This is equivalent to using if-statements to check throw values although some might argue it is clearer to read. An if-statement equivalent would be:

from math import hypot, ceil


def score(x, y):
    throw =  ceil(hypot(x, y))
    
    if throw in (0, 1): return 10
    if throw in (2, 3, 4, 5): return 5
    if throw in (6, 7, 8, 9, 10): return 1
    
    return 0

One can also use <, >, or <= and >= in structural pattern matching, although the syntax becomes almost identical to using them with if-statements, but more verbose:

from math import hypot, ceil


def score(x, y):
    throw = ceil(hypot(x, y))
    
    match throw:
        case throw if throw <= 1: return 10
        case throw if throw <= 5: return 5
        case throw if throw <= 10: return 1
        case _: return 0

Finally, one can use an assignment expression or walrus operator to calculate the throw value rather than calculating and assigning a variable on a separate line. This isn't necessary (the first variations shows this clearly) and might be harder to reason about/understand for some programmers:

from math import hypot, ceil

def score(x, y):
    match throw := ceil(hypot(x, y)):
        case throw if throw <= 1: return 10
        case throw if throw <=5: return 5
        case throw if throw <=10: return 1
        case _: return 0

Using structural pattern matching for this exercise doesn't offer any clear performance advantages over the if-statement, but might be "cleaner", more "organized looking", or easier for others to scan/read.

7th May 2025 · Found it useful?