<p>You are given a <strong>2D</strong> integer array <code>coordinates</code> and an integer <code>k</code>, where <code>coordinates[i] = [x<sub>i</sub>, y<sub>i</sub>]</code> are the coordinates of the <code>i<sup>th</sup></code> point in a 2D plane.</p>

<p>We define the <strong>distance</strong> between two points <code>(x<sub>1</sub>, y<sub>1</sub>)</code> and <code>(x<sub>2</sub>, y<sub>2</sub>)</code> as <code>(x1 XOR x2) + (y1 XOR y2)</code> where <code>XOR</code> is the bitwise <code>XOR</code> operation.</p>

<p>Return <em>the number of pairs </em><code>(i, j)</code><em> such that </em><code>i &lt; j</code><em> and the distance between points </em><code>i</code><em> and </em><code>j</code><em> is equal to </em><code>k</code>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> coordinates = [[1,2],[4,2],[1,3],[5,2]], k = 5
<strong>Output:</strong> 2
<strong>Explanation:</strong> We can choose the following pairs:
- (0,1): Because we have (1 XOR 4) + (2 XOR 2) = 5.
- (2,3): Because we have (1 XOR 5) + (3 XOR 2) = 5.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> coordinates = [[1,3],[1,3],[1,3],[1,3],[1,3]], k = 0
<strong>Output:</strong> 10
<strong>Explanation:</strong> Any two chosen pairs will have a distance of 0. There are 10 ways to choose two pairs.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>2 &lt;= coordinates.length &lt;= 50000</code></li>
	<li><code>0 &lt;= x<sub>i</sub>, y<sub>i</sub> &lt;= 10<sup>6</sup></code></li>
	<li><code>0 &lt;= k &lt;= 100</code></li>
</ul>

class Solution:
    def countPairs(self, coordinates: List[List[int]], k: int) -> int:

        coordinates = tuple(sorted(map(tuple, coordinates)))
        counts = Counter(coordinates)
        # print(f'{counts=}')

        # okay, so we define (1) A as (x1 XOR x2) and (2) B as (y1 XOR y2).
        # which means we're looking for distance = (3) A + B = k.
        # since XOR is its own inverse, equation 1 means (4) x2 = (A XOR x1)
        # and eq. 2 means (5) y2 = B XOR y1; also, eq. 3 means (6) B = k - A.
        # substitute eq. 6 into eq. 5 and you get (7) y2 = (k - A) XOR y1.
        # So, equation 4 gives you x2 from x1, given a particular A,
        # and equation 7 gives you y2 from y1, given a value for A as well.
        # This means we can loop through possible values of A, and determine
        # the proper (x2, y2) for each (x1, y1) pair.
        # And A can only take on a value <= k, and k can only be 0 .. 100.
        # (I had thought that the Xs and Ys can be up to 20 bits, but the
        # k maximum puts a hard cap on A)

        answer = 0
        for P1 in coordinates:
            (x1, y1) = P1
            # print(f'{(x1,y1)=}')
            counts[P1] -= 1
            if not counts[P1]:
                del counts[P1]
            # print(f'  {counts=}')
            for A in range(k+1):
                x2 = (A ^ x1)       # "^" == XOR
                y2 = (k - A) ^ y1
                # print(f'  {A=} {(x2,y2)=}')
                if (x2,y2) in counts:
                    # print(f'  {A=} {(x2,y2)}: YES (+{counts[(x2,y2)]})')
                    # print(f'    YES (+{counts[(x2,y2)]})')
                    answer += counts[(x2,y2)]
                # else:
                #     # print(f'    NO')

        return answer

2142