# Problem Description
This is a problem about generating string values for nodes in a complete binary tree where:
- Each node has a string value composed of '<' and '>' characters
- The value of each node is determined by its path from the root
- We need to return the string value for any given node number (1-based indexing)
- The root node (1) starts with an empty string
- Each node's value is built by combining its parent's value with the edge value leading to it

# Visual Facts
1. Tree Structure:
   - Complete binary tree with nodes numbered 1, 2, 3, ...
   - Root is node 1
   - Left child = 2×parent, Right child = 2×parent + 1

2. Edge Patterns by Layer:
   - Layer 1 (Root to level 1): Left = ">", Right = ">"
   - Layer 2 (Level 1 to 2): Left = "<", Right = "<"
   - Layer 3 (Level 2 to 3): Left = ">", Right = ">"

3. Node Values (Examples):
   - Node 1: Empty string
   - Node 2: ">"
   - Node 3: ">"
   - Node 4: "><"
   - Node 5: "><"
   - Node 6: "><"
   - Node 7: "><"
   - Node 8: "><>"

# Visual Patterns
1. Edge Pattern Rule:
   - Odd-numbered layers: Left = ">", Right = ">"
   - Even-numbered layers: Left = "<", Right = "<"

2. Node Value Construction:
   - Each node's value = Parent's value + Edge value
   - Value length increases by 1 at each level
   - Level 0 (root): length 0
   - Level 1: length 1
   - Level 2: length 2
   - And so on...

3. String Building Pattern:
   - Each node's string is built by concatenating all edge values in the path from root
   - The path can be determined by tracking parent references until reaching root

# Solution
import math

def solution(node: int) -> str:
    """
    Returns the string value at the given node position in a tree's growth pattern.

    Parameters:
        node (int): The 1-based index position of the node to query.

    Returns:
        str: The string value stored at the specified node. Return '' if the value is empty.   
    """
    if node == 1:
        return ""
    
    result = []
    current = node

    while current > 1:
        level = math.floor(math.log2(current)) - 1
        if level % 2 == 1:
            if current % 2 == 0:
                result.append("<")
            else:
                result.append("<")
        else:
            if current % 2 == 0:
                result.append(">")
            else:
                result.append(">")

        current //= 2

    return "".join(result[::-1])


# Test Script
def test():
    test_cases = [
        (1, ""),
        (2, ">"),
        (3, ">"),
        (6, "><"),
        (5, "><"),
        (9, "><>"),
        (10, "><>"),
        (11, "><>"),
        (14, "><>"),
        (17, "><><")
    ]

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

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

test()