# Complete DOCPLEX implementation - Retry Attempt 4

from docplex.mp.model import Model

def optimize_student_elections():
    # 1. MODEL & DATA SETUP
    mdl = Model(name="student_elections")
    
    # Voting data for each student and position
    votes = [
        [25, 18, 22, 15, 30, 20],  # Student 1
        [30, 25, 20, 18, 28, 22],  # Student 2
        [20, 30, 25, 22, 18, 25]   # Student 3
    ]
    
    n_students = len(votes)
    n_positions = len(votes[0])
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert all(len(v) == n_positions for v in votes), "Array length mismatch"
    safe_range_students = range(n_students)
    safe_range_positions = range(n_positions)
    
    # 2. VARIABLES
    # Binary decision variables for each student and position
    x = {(i, j): mdl.binary_var(name=f"x_{i}_{j}") for i in safe_range_students for j in safe_range_positions}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize the total number of votes received by the elected representatives
    objective = mdl.sum(votes[i][j] * x[i, j] for i in safe_range_students for j in safe_range_positions)
    mdl.maximize(objective)
    
    # 4. CONSTRAINTS - CORRECT SYNTAX PATTERNS
    
    # Each position must be filled by exactly one student
    for j in safe_range_positions:
        mdl.add_constraint(mdl.sum(x[i, j] for i in safe_range_students) == 1, ctname=f"position_{j}_filled")
    
    # Each student can hold at most one position
    for i in safe_range_students:
        mdl.add_constraint(mdl.sum(x[i, j] for j in safe_range_positions) <= 1, ctname=f"student_{i}_limit")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in safe_range_students:
            for j in safe_range_positions:
                if solution.get_value(x[i, j]) > 0.5:  # Binary variable, so check > 0.5
                    print(f"Student {i+1} is elected to position {j+1}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")

    return mdl

# Run the optimization
optimize_student_elections()