Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Number of Boomerangs in Python
A boomerang in computational geometry is a tuple of points (i, j, k) where the distance from point i to point j equals the distance from point i to point k. Given n distinct points in a plane, we need to count all possible boomerangs.
For example, with points [[0,0],[1,0],[2,0]], we can form boomerangs like [[1,0],[0,0],[2,0]] and [[1,0],[2,0],[0,0]] where point [1,0] is equidistant from [0,0] and [2,0].
Algorithm
The approach uses a distance-counting strategy ?
For each point as a potential center point
Calculate distances from this center to all other points
Count how many points share the same distance
If n points share the same distance, we can form n × (n-1) boomerangs
Implementation
from collections import defaultdict
def numberOfBoomerangs(points):
counter_of_boomerangs = 0
for point_1 in points:
x1, y1 = point_1
distance_count_dict = defaultdict(int)
# Calculate distances from current point to all points
for point_2 in points:
x2, y2 = point_2
diff_x = x2 - x1
diff_y = y2 - y1
# Use squared distance to avoid floating point issues
dist = diff_x ** 2 + diff_y ** 2
distance_count_dict[dist] += 1
# Count boomerangs for each distance
for d in distance_count_dict:
n = distance_count_dict[d]
# n points at same distance can form n*(n-1) boomerangs
counter_of_boomerangs += n * (n - 1)
return counter_of_boomerangs
# Test the function
points = [[0,0],[1,0],[2,0]]
result = numberOfBoomerangs(points)
print(f"Number of boomerangs: {result}")
Number of boomerangs: 2
How It Works
Let's trace through the example [[0,0],[1,0],[2,0]] ?
def numberOfBoomerangs_with_trace(points):
counter_of_boomerangs = 0
for i, point_1 in enumerate(points):
print(f"Center point: {point_1}")
x1, y1 = point_1
distance_count_dict = defaultdict(int)
for point_2 in points:
x2, y2 = point_2
diff_x = x2 - x1
diff_y = y2 - y1
dist = diff_x ** 2 + diff_y ** 2
distance_count_dict[dist] += 1
print(f"Distance counts: {dict(distance_count_dict)}")
for d in distance_count_dict:
n = distance_count_dict[d]
boomerangs_for_this_distance = n * (n - 1)
counter_of_boomerangs += boomerangs_for_this_distance
if boomerangs_for_this_distance > 0:
print(f"Distance {d}: {n} points ? {boomerangs_for_this_distance} boomerangs")
print()
return counter_of_boomerangs
points = [[0,0],[1,0],[2,0]]
result = numberOfBoomerangs_with_trace(points)
print(f"Total boomerangs: {result}")
Center point: [0, 0]
Distance counts: {0: 1, 1: 1, 4: 1}
Center point: [1, 0]
Distance counts: {0: 1, 1: 2}
Distance 1: 2 points ? 2 boomerangs
Center point: [2, 0]
Distance counts: {0: 1, 4: 1, 1: 1}
Total boomerangs: 2
Key Points
Distance Formula: We use squared distance (x?-x?)² + (y?-y?)² to avoid floating point precision issues
Permutation Count: For n points at the same distance, we get n×(n-1) ordered pairs
Time Complexity: O(n²) where n is the number of points
Space Complexity: O(n) for the distance dictionary
Conclusion
The boomerang counting algorithm efficiently finds all valid point triplets by grouping points by their distance from each center point. The key insight is that n points equidistant from a center can form n×(n-1) boomerangs.
