# Complete DOCPLEX implementation

from docplex.mp.model import Model

def gymnastics_optimization():
    """Optimize gymnast event participation to maximize total points."""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="gymnastics_optimization")
    
    # Data from the database
    points = [
        [12, 10, 14, 15, 11, 9],   # Gymnast 1
        [18, 16, 17, 19, 14, 13],  # Gymnast 2
        [14, 12, 15, 17, 13, 11]   # Gymnast 3
    ]
    
    max_events_per_gymnast = 3
    max_gymnasts_per_event = 5
    
    n_gymnasts = len(points)
    n_events = len(points[0])
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert all(len(p) == n_events for p in points), "Array length mismatch"
    safe_range_gymnasts = range(n_gymnasts)
    safe_range_events = range(n_events)
    
    # 2. VARIABLES
    x = {(i, j): mdl.binary_var(name=f"x_{i}_{j}") for i in safe_range_gymnasts for j in safe_range_events}
    
    # 3. OBJECTIVE FUNCTION
    objective = mdl.sum(points[i][j] * x[i, j] for i in safe_range_gymnasts for j in safe_range_events)
    mdl.maximize(objective)
    
    # 4. CONSTRAINTS
    
    # Maximum events per gymnast
    for i in safe_range_gymnasts:
        mdl.add_constraint(mdl.sum(x[i, j] for j in safe_range_events) <= max_events_per_gymnast, ctname=f"max_events_gymnast_{i}")
    
    # Maximum gymnasts per event
    for j in safe_range_events:
        mdl.add_constraint(mdl.sum(x[i, j] for i in safe_range_gymnasts) <= max_gymnasts_per_event, ctname=f"max_gymnasts_event_{j}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in safe_range_gymnasts:
            for j in safe_range_events:
                value = solution.get_value(x[i, j])
                if value > 1e-6:
                    print(f"Gymnast {i} participates in event {j}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

# Run the optimization
gymnastics_optimization()