Determine whether points form squares
Company: Purestorage
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Quick Answer: This question evaluates computational geometry, combinatorial counting, and algorithmic optimization skills by requiring validation of a non-degenerate square from four 2D integer points and counting distinct squares in a larger point set, and it falls under the Coding & Algorithms category.
Validate a Single Square
Constraints
- Exactly 4 points are provided.
- Coordinates fit in 32-bit signed integers.
- Coincident points or collinear points do not form a square.
- The square may be rotated (not necessarily axis-aligned).
Examples
Input: [[0,0],[0,1],[1,1],[1,0]]
Expected Output: True
Explanation: Unit axis-aligned square.
Input: [[0,0],[2,1],[3,-1],[1,-2]]
Expected Output: True
Explanation: Rotated square with side² = 5 and diagonal² = 10.
Input: [[0,0],[0,2],[3,2],[3,0]]
Expected Output: False
Explanation: A 3x2 rectangle — sides unequal, not a square.
Input: [[0,0],[1,1],[1,0],[0,0]]
Expected Output: False
Explanation: Two vertices coincide (degenerate).
Input: [[0,0],[0,0],[0,0],[0,0]]
Expected Output: False
Explanation: All points identical — fully degenerate.
Input: [[1,0],[-1,0],[0,1],[0,-1]]
Expected Output: True
Explanation: Square rotated 45 degrees, centered at origin.
Input: [[0,0],[0,3],[4,0],[4,3]]
Expected Output: False
Explanation: A 4x3 rectangle, not a square.
Hints
- Avoid floating point: compare *squared* distances so all math stays in integers.
- Collect all 6 pairwise squared distances and sort them.
- A valid square: the 4 smallest are equal (sides, > 0) and the 2 largest are equal and equal to 2× the side² (diagonals).
Count Squares in a Point Set
Constraints
- 1 <= N <= 2e4 for the optimized discussion.
- Coordinates fit in 32-bit signed integers.
- Duplicate coordinates are collapsed and cannot form a square.
- A square counts once regardless of vertex order; rotated squares count.
Examples
Input: [[0,0],[0,1],[1,1],[1,0]]
Expected Output: 1
Explanation: A single unit square.
Input: [[0,0],[0,1],[1,1],[1,0],[2,0],[2,1]]
Expected Output: 2
Explanation: A 2x3 grid of points forms two adjacent unit squares.
Input: [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]
Expected Output: 6
Explanation: 3x3 grid: four 1x1 squares, one 2x2 square, and one rotated square (0,1),(1,2),(2,1),(1,0).
Input: [[0,0],[2,1],[3,-1],[1,-2]]
Expected Output: 1
Explanation: Four vertices of one rotated square.
Input: []
Expected Output: 0
Explanation: No points, no squares.
Input: [[0,0]]
Expected Output: 0
Explanation: A single point cannot form a square.
Input: [[0,0],[5,5],[5,0],[0,5]]
Expected Output: 1
Explanation: One 5x5 axis-aligned square.
Input: [[0,0],[0,0],[0,1],[1,1],[1,0]]
Expected Output: 1
Explanation: Duplicate point collapses; still exactly one unit square.
Input: [[0,0],[1,0],[2,0],[3,0]]
Expected Output: 0
Explanation: All collinear points — no square possible.
Hints
- Put all distinct points in a hash set for O(1) average membership tests.
- Treat each pair of points as a diagonal of a candidate square; the perpendicular bisector of equal length gives the other two vertices.
- Derived vertex coordinates may be non-integer (half values) — skip those (a real lattice square would land on integer coordinates).
- Each square has two diagonals, so it is counted twice — divide the total by 2.