# Score a curling end

Curling is a sport where two teams aim to place stones as close to the centre of a target as possible. The winner of a curling end is the team whose stone is closest to the centre – they score as many points as the number of their stones closer to the centre than any of their opponents.

Given two lists of pairs of integers representing the Cartesian coordinates of both teams' stones, with the origin as target centre, output a positive integer if one team wins and a negative integer if the other wins; the sign must be consistent with input order. The magnitude of this integer is the number of points scored.

Ties are broken as follows:

• If there are no stones at all or there is a tie between teams for the closest stone, no points are scored and 0 should be returned.
• If there is a winning team, any of their stones at exactly the same distance as their opponent's closest stone do not count for points.

Input formatting is flexible – you may use a complex number to represent a stone's coordinates or tag the coordinates with their corresponding teams, for example. The distance of (x,y) from the origin is $$\\sqrt{x^2+y^2}\$$ – scaling is equal in both directions.

This is ; fewest bytes wins.

## Test cases

These assume the team whose stones' coordinates are listed first is associated with a positive output.

[],[] -> 0
[(1,0)],[] -> 1
[],[(0,1)] -> -1
[(2,0),(2,1),(2,2),(2,-1),(2,-2),(-2,-2),(-2,-1),(-2,0),(-2,1),(-2,2)],[(0,1),(0,-1)] -> -2
[(4,3),(3,3),(-3,-3),(-1,0)],[(4,1)] -> 1
[(-3,2)],[(2,2),(0,-8),(-1,-1),(3,6)] -> -2
[(0,0),(1,0),(0,1)],[(1,1),(1,-1),(-1,1),(-1,-1)] -> 3
[(-7,1)],[(5,5)] -> 0
[(1,0),(2,0)],[(-2,0)] -> 1
[(-3,-4),(0,5)],[(-1,2),(4,3),(4,-3),(-3,0)] -> -2


Obviously this question was inspired by the curling events at the 2022 Winter Olympics.

• Why can teams have unequal numbers of stones? Feb 9, 2022 at 9:36
• @chunes In actual curling stones can be taken out of play by hitting other stones into them, and only stones within the target at the end of an end are counted. Note that test case 4 has team 1 having 10 stones, which is not possible in actual curling as each team has only 8 stones an end (and 5 to throw in doubles). This is a generalisation of sorts. Feb 9, 2022 at 9:45

# APL(Dyalog Unicode), 14 bytes SBCS

(¯1⊥1⊥¨⌽<⌊/¨)|


Try it on APLgolf!

A tacit function which takes the coordinates as a pair of vectors of complex numbers.

| Absolute value on each of the complex numbers in the input.
(...) Apply the inner function on the absolute values.
⌊/¨ Get the minimum of each of the vectors.
⌽< For each value in a vector, check if it is less than the minimum of the other vector.
1⊥¨ Sum each boolean vector.
¯1⊥ Get the difference between the two results.

The two uses of Decode ⊥ are usually the reductions +/¨ and -⍨/, but they don't work so well in a tacit function as they have to be called monadically.

• What is a train submission? Feb 9, 2022 at 8:50
• @ParclyTaxel That is a type of function in APL and the answer template from APLgolf includes that wording. But I agree it might a bit confusing, so I changed it.
– ovs
Feb 9, 2022 at 8:52
• I'll change the template today. Feb 9, 2022 at 10:17
• changes are live now Feb 9, 2022 at 10:35

# Python3, 79 bytes:

f=lambda x,y,w=1:sum(y==[]or abs(j)<min(map(abs,y))for j in x)-(w and f(y,x,0))


Try it online!

• If you take coordinates as complex numbers the second function simplifies to p=lambda t:[*map(abs,t)]. And you might want to look into making the first function recursive to get rid of the duplicated sums.
– ovs
Feb 9, 2022 at 12:05
• Not sure about the 100 - there are no bounds given in the question; I'd ask the OP about that before using it. If a bound is given then it's likely that you could use 99. Using complex numbers and this bound you can save 28 using another helper function and moving the +[99] into the p function as an or[99] like so: TIO. Feb 9, 2022 at 12:22
• @JonathanAllan Thanks, updated. Feb 9, 2022 at 12:24
• ...96 actually - TIO Feb 9, 2022 at 12:24
• 79 without any assumptions on bounds.
– ovs
Feb 9, 2022 at 14:27

# Charcoal, 26 bytes

ＦθＵＭιΣＸκ²Ｉ↨ＥθＬΦ§θ¬κ⬤ι‹λν±¹


Try it online! Link is to verbose version of code. Takes input as a pair of lists of tuples. Explanation:

Ｆθ


Loop over each team.

ＵＭιΣＸκ²


Replace each stone with its squared distance from the origin.

Ｉ↨ＥθＬΦ§θ¬κ⬤ι‹λν±¹


For each team, count how many stones are nearer than all of the other team's stones, then output the difference between the two values. (This particular formulation has been chosen because it works with empty lists.)

# JavaScript (Node.js), 144 bytes

(n,k,Z=Math.min,N=(F=L=>L.map(([x,y])=>x*x+y*y))(n),K=F(k),Q=Z(...N),R=Z(...K),G=(c,d)=>c.filter(e=>d.every(E=>e<E)).length)=>Q<R?G(N,K):-G(K,N)


Try it online!

I hope it can be golfed further.

• No need for the ternary operator, just return G(N,K)-G(K,N). Deleting then obsolete functions Z, Q and R gives 109 bytes. Feb 9, 2022 at 21:22

# Burlesque, 49 bytes

m{m{)S[++}}Jqnuay{)L[}{J)<]<-{bxq.<_+fl}Z]}IE^p.-


Try it online!

There are issues with finding the minimum of an empty vector, so there needs to be a workaround.

m{      # Map
m{     # Map
)S[  # Square each
++    # Sum
}      # -- Calc Mag sq
}       # -- Of each input
J       # Duplicate
qnuay   # If any empty
{       #
)L[    # Map to length
}       #
{       # Else
J      # Duplicate
)<]    # Map to minima
<-     # Reverse
{      #
bx    # Box Number
q.<_+ # Append <
fl    # Count
}      # -- Count those less than minimum of other side
Z]     # Zip with apply
}IE     # If Else (stack based)
^p      # Push to stack
.-      # Subtraction


# Vyxalḋ, 23 bytes

I'd like to make code that works with strictly nested array-input, include empty arrays: [ [], [] ], [ [], [[0, 1]] ] etc.
I’d appreciate it if someone would do the refactoring, but with that condition in mind.

:vL:A[_vƛ∆/;:vgṘ¨Z<∑]÷-


Try it Online!

       # ḋ flag (Print rationals in their decimal form) useful for debugging
:vL:A  # Check if all arrays are not empty (and get lenghts)
[      # If so
_vƛ∆/; # Remove lengths and calculate all norms in both arrays
:vg    # Find minima
Ṙ      # Reverse
¨Z‹∑   # Zip, check for "less than" and sum boolean
]÷-    Find difference (in both cases: lengths or sums)


# Wolfram Language (Mathematica), 85 bytes

c=Count[#1,u_/;u<Min@#2]&;
f=c@@#-c@@Reverse@#&@Map[Norm,#/.{{}->{\[Infinity]}},{2}]&


Try it online!

This works with strictly nested array-input, include empty arrays: [ [], [] ], [ [], [[0, 1]] ] etc.
Mathematica has built-in Infinity, so I use it to replace empty results (as if stones cast far away).
Code is clumsy so I hope someone post more well-built answer