# Complete GUROBIPY implementation - Retry Attempt 1

import gurobipy as gp
from gurobipy import GRB

def climbing_assignment_optimization():
    # 1. MODEL & DATA SETUP
    model = gp.Model("climbing_assignment")
    
    # Data from the database
    climber_ids = [1, 2, 3]
    mountain_ids = [1, 2, 3]
    
    points = {
        (1, 1): 10,
        (2, 2): 20,
        (3, 3): 30
    }
    
    time_spent = {
        (1, 1): 5,
        (2, 2): 10,
        (3, 3): 15
    }
    
    total_time_limit = 100
    
    # CRITICAL: Validate array lengths before loops
    assert len(climber_ids) == len(mountain_ids), "Climber and Mountain ID length mismatch"
    
    # 2. VARIABLES
    x = model.addVars(climber_ids, mountain_ids, vtype=GRB.BINARY, name="x")
    
    # 3. OBJECTIVE FUNCTION
    model.setObjective(gp.quicksum(points[i, j] * x[i, j] for i in climber_ids for j in mountain_ids), GRB.MAXIMIZE)
    
    # 4. CONSTRAINTS
    # Total Time Constraint
    model.addConstr(gp.quicksum(time_spent[i, j] * x[i, j] for i in climber_ids for j in mountain_ids) <= total_time_limit, name="total_time_limit")
    
    # Single Assignment Constraint
    for i in climber_ids:
        model.addConstr(gp.quicksum(x[i, j] for j in mountain_ids) == 1, name=f"single_assignment_{i}")
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in climber_ids:
            for j in mountain_ids:
                if x[i, j].x > 0.5:
                    print(f"Climber {i} assigned to Mountain {j}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

# Execute the optimization
climbing_assignment_optimization()