# Problem Description
Given an x-coordinate where a red dot intersects with the bottom edge of a square in an inverted pyramid, determine the number of that square. If the dot hits exactly on an edge between squares, return -1.

# Visual Facts
1. Physical Structure:
   - Inverted pyramid made of equal-sized squares
   - Base square (1) centered at x=0
   - Each layer adds one more square than the previous layer
   - Each square has the same width of 1 unit

2. Coordinate System:
   - X-axis runs from negative to positive
   - Square 1 spans x ∈ [-0.5, 0.5]

3. Square Numbering (from left to right):
   - Bottom layer: 1
   - Second layer: 2, 3
   - Third layer: 4, 5, 6
   - Fourth layer: 7, 8, 9, 10
   - Fifth layer: 11, 12, 13, 14, 15
   - Sixth layer: 16, 17, ...

4. Test Cases:
   - Case 1: x=-1.25 → N=4
   - Case 2: x=2.3 → N=15
   - Case 3: x=1 → N=-1 (edge case)

# Visual Patterns
1. Layer Properties:
   - Layer L has L squares
   - upper(|x|/0.5) determines the layer number
   - Sign of x determines left (-) or right (+) side
   - the red dot can only intersect with the first or last square of a layer

2. Square Position Formula:
   - For layer L:
     * Left side (first) square: N = 1+2+...+(L-1)+1 = 1+(L-1)(L)/2
     * Right side (last) square: N = 1+2+...+L = L(L+1)/2
   - For x=-1.25, L=upper(|-1.25|/0.5)=3, left side, N=1+2+1=4
   - For x=2.3, L=upper(|2.3|/0.5)=5, right side, N=1+2+3+4+5=15

3. Edge Detection:
   - When x is a multiple of 0.5, it's an edge point
   - Edge points should return -1
   - For x=1, edge case, N=-1


# Solution
def solution(x: float) -> int:
    """
    Determines the square's number 'n' in an inverted pyramid of squares given the x-coordinate of a red dot.

    Parameters:
        x (float): The x-coordinate of the red dot.

    Returns:
        int: The located square's number 'n'.
    """
    row_start = 1
    row_length = 1
    
    while True:
        min_x = -(row_length) / 2
        max_x = (row_length) / 2
        if min_x <= x <= max_x:
            if x == min_x or x == max_x:  
                return -1
            
            col_index = int(x - min_x)
            n = row_start + col_index
            return n
        
        row_start += row_length
        row_length += 1


# Test Script
def test():
    test_cases = [
        (0.23, 1),
        (-0.23, 1),
        (0.27, 1),
        (2, -1),
        (-1.25, 4),
        (0.772, 3),
        (-0.99, 2),
        (-2.8, 16),
        (-2.2, 11),
        (2.99, 21)
    ]

    for x, expected_output in test_cases:
        try:
            output = solution(x)
        except Exception as e:
            error_message = (
                f"An exception occurred while running the test case:\n"
                f"`x`: {x}\n\n"
                f"Exception: '{str(e)}'"
            )
            assert False, error_message

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

test()