Medium

Detect Squares

Description

Store points with multiplicity. count(query) returns how many positive-area axis-aligned squares can be formed using query and three stored point occurrences. The query itself need not have been stored.

Solution

from collections import Counter

def create_detect_squares():
    return Counter()

def add(state, point):
    state[tuple(point)] += 1

def count(state, point):
    x, y = point
    total = 0
    for (px, py), frequency in state.items():
        if px == x and py != y:
            side = py - y
            for nx in (x + side, x - side):
                total += frequency * state[(nx, y)] * state[(nx, py)]
    return total

Examples

Example 1

Input
[["DetectSquares"],["add",[3,10]],["add",[11,2]],["add",[3,2]],["count",[11,10]],["count",[14,8]],["add",[11,2]],["count",[11,10]]]
Output
[null,null,null,null,1,0,null,2]

Duplicating one stored corner doubles the square count.

Example 2

Input
[["DetectSquares"],["count",[0,0]]]
Output
[null,0]

There are no stored corners.

Example 3

Input
[["DetectSquares"],["add",[0,0]],["add",[0,1]],["count",[0,2]]]
Output
[null,null,null,0]

Collinear points cannot make a square.

Approach

Count stored coordinate pairs. For each stored point vertically aligned with the query, use their vertical difference as the square side length. Check the two possible horizontal directions and multiply the three corner frequencies.

Time & space

add: expected O(1) time. count: O(P) time and O(1) auxiliary space, where P is distinct stored point count. Persistent storage is O(P).