# Problem Description
The problem involves identifying watchtowers that are not connected to any other watchtowers based on specific connection rules. Each watchtower is represented by its coordinates in a 2D plane. A watchtower is considered connected if there is at least one other watchtower within a radius of 3 units from it. The task is to return the coordinates of the watchtowers that are not connected to any other watchtower.

# Visual Facts
1. The image shows two examples of watchtower configurations on a 2D grid.
2. Each watchtower is represented by a unique coordinate (x, y).
3. The radius of connectivity is given as 3 units.
4. Green lines indicate connected watchtowers.
5. Red dashed lines indicate distances greater than 3 units, showing non-connected watchtowers.
6. Blue circles with radius 3 are drawn around each watchtower to visualize the connectivity range.
7. Watchtowers are marked in yellow if they are not connected to any other watchtower.

# Visual Patterns
1. A watchtower is connected to another if the Euclidean distance between them is less than or equal to 3 units.
2. The Euclidean distance formula is used to determine connectivity:  \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2} .
3. If no other watchtower falls within the circle of radius 3 centered at a given watchtower, it is considered not connected.
4. The problem involves iterating over each watchtower and checking its distance to all other watchtowers to determine connectivity.
5. The output is a set of coordinates of watchtowers that have no other watchtowers within the 3-unit radius.


# Solution
from typing import Tuple, Set

def solution(towers: Set[Tuple[int, int]]) -> Set[Tuple[int, int]]:
    """
    Identifies watchtowers that are not connected to any others based on given connection rules.

    Args:
        towers: A set of tuples, each containing (x, y) coordinates of a watchtower.

    Returns:
        A set of tuples containing (x, y) coordinates of unconnected watchtowers.
    """
    unconnected = set()  # To store unconnected watchtowers
    towers = list(towers)  # Convert set to list for easier indexing

    for i in range(len(towers)):
        x_i, y_i = towers[i]
        is_connected = False

        # Check all other watchtowers
        for j in range(len(towers)):
            if i == j:
                continue  # Skip the same watchtower
            x_j, y_j = towers[j]

            # Calculate Euclidean distance
            distance_squared = (x_j - x_i) ** 2 + (y_j - y_i) ** 2

            # If distance is within radius 3, mark as connected
            if distance_squared <= 9:  # 3^2 = 9
                is_connected = True
                break

        # If no other watchtower is within radius 3, add to unconnected set
        if not is_connected:
            unconnected.add((x_i, y_i))

    return unconnected


# Test Script
def test():
    test_cases = [
        {
            "input": set(()),
            "expected": set()
        },
        {
            "input": set([(1,1), (3,4), (10,10), (10,13)]),
            "expected": set([(1,1), (3,4)])
        },
        {
            "input": set([(1,1), (1,2), (0,11), (0,8), (0,14.1)]),
            "expected": set([(0, 14.1)])
        },
        {
            "input": set([(1,1), (2,2)]),
            "expected": set()
        },
        {
            "input": set([(0,0), (0,1), (1,0), (1,1)]),
            "expected": set()
        },
        {
            "input": set([(2,3), (2,5), (3,5), (3,4)]),
            "expected": set()
        },
        {
            "input": set([(0,0), (1,1), (2,2), (2,3),(0,8)]),
            "expected": set([(0,8)])
        },
        {
            "input": set([(1,1), (1,2), (2,2), (5,5), (5,6), (6,5), (10,10)]),
            "expected": set([(10,10)])
        },
    ]

    for i, tc in enumerate(test_cases, start=1):
        towers_input = tc["input"]
        expected_output = tc["expected"]
        
        try:
            output = solution(towers_input)
        except Exception as e:
            error_message = (
                f"An exception occurred while running the test case:\n"
                f"`towers`: {towers_input}\n\n"
                f"Exception: '{str(e)}'"
            )
            assert False, error_message

        if output != expected_output:
            error_message = (
                f"The following Test Case failed:\n"
                f"`towers`: {towers_input}\n\n"
                f"Actual Output: {output}\n"
                f"Expected Output: {expected_output}"
            )
            assert False, error_message

test()