You have a very large square wall and a circular dartboard placed on the wall. You have been challenged to throw darts into the board blindfolded. Darts thrown at the wall are represented as an array of points on a 2D plane. 
Return the maximum number of points that are within or lie on any circular dartboard of radius r.
Example 1:
Input: points = [[-2,0],[2,0],[0,2],[0,-2]], r = 2
Output: 4
Explanation: Circle dartboard with center in (0,0) and radius = 2 contain all points.
Example 2:
Input: points = [[-3,0],[3,0],[2,6],[5,4],[0,9],[7,8]], r = 5
Output: 5
Explanation: Circle dartboard with center in (0,4) and radius = 5 contain all points except the point (7,8).
Example 3:
Input: points = [[-2,0],[2,0],[0,2],[0,-2]], r = 1
Output: 1
Example 4:
Input: points = [[1,2],[3,5],[1,-1],[2,3],[4,1],[1,3]], r = 2
Output: 4
Constraints:
1 <= points.length <= 100
points[i].length == 2
-10^4 <= points[i][0], points[i][1] <= 10^4
1 <= r <= 5000
class Solution:
    def numPoints(self, points: List[List[int]], r: int) -> int:
        @functools.lru_cache(None)
        def find(cx, cy, r):
            ans = 0
            for x, y in points:
                if (x-cx) ** 2 + (y-cy) ** 2 <= r ** 2 + 1e-6:
                    ans += 1
            return ans
        
        ans = 1
        for i in range(len(points)):
            x1, y1 = points[i]
            for j in range(i+1, len(points)):
                x2, y2 = points[j]
                deno = (y1-y2) ** 2 + (x1-x2) ** 2
                if deno > 4 * r * r:
                    continue
                k = math.sqrt(r * r / deno - 0.25)
                ans = max(ans, max(find((x1+x2)/2 + t*(y1-y2), (y1+y2)/2 - t * (x1-x2), r) for t in (k, -k)))
        return ans
class Solution:
    def numPoints(self, points: List[List[int]], r: int) -> int:
        @functools.lru_cache(None)
        def find(cx, cy, r):
            ans = 0
            for x, y in points:
                if (x-cx) ** 2 + (y-cy) ** 2 <= r ** 2 + 1e-6:
                    ans += 1
            return ans
        
        ans = 1
        for i in range(len(points)):
            x1, y1 = points[i]
            for j in range(i+1, len(points)):
                x2, y2 = points[j]
                deno = (y1-y2) ** 2 + (x1-x2) ** 2
                if deno > 4 * r * r:
                    continue
                k = math.sqrt(r * r / deno - 0.25)
                ans = max(ans, max(find((x1+x2)/2 + t*(y1-y2), (y1+y2)/2 - t * (x1-x2), r) for t in (k, -k)))
        return ans