--- Final Solver (used for performance test) ---
import numpy as np
from numba import njit
from typing import Any

@njit
def _solve_proj(y):
    n = y.size
    if n == 0:
        return np.empty(0, dtype=np.float64)
    if n == 1:
        return np.ones(1, dtype=np.float64)
    
    # Work on a copy of y (values only, partition in-place)
    arr = y.copy()
    left = 0
    right = n
    s = 0.0
    rho = 0
    
    while left < right:
        m = right - left
        # Choose pivot as first element (fast)
        pivot = arr[left]
        
        # Partition in-place: move > pivot to beginning, < pivot to end
        # We'll do three-way partition
        i = left
        j = left
        k = right - 1
        sum_gt = 0.0
        cnt_gt = 0
        sum_eq = 0.0
        cnt_eq = 0
        
        # First pass: count and compute sums for G, E, L
        # We'll use a simpler approach: just compute sums/counts then rearrange
        for idx in range(left, right):
            val = arr[idx]
            if val > pivot:
                cnt_gt += 1
                sum_gt += val
            elif val == pivot:
                sum_eq += val
                cnt_eq += 1
        
        cnt_le = m - cnt_gt - cnt_eq
        
        val_a = s + sum_gt - (rho + cnt_gt) * pivot
        if val_a > 1.0 + 1e-12:
            # Keep only G: move G values to arr[left:left+cnt_gt]
            # We'll compact them
            j = left
            for idx in range(left, right):
                if arr[idx] > pivot:
                    arr[j] = arr[idx]
                    j += 1
            right = j
        elif s + sum_gt + sum_eq - (rho + cnt_gt + cnt_eq) * pivot < 1.0 - 1e-12:
            # Keep only L
            s += sum_gt + sum_eq
            rho += cnt_gt + cnt_eq
            j = left
            for idx in range(left, right):
                if arr[idx] < pivot:
                    arr[j] = arr[idx]
                    j += 1
            right = j
        else:
            s += sum_gt
            rho += cnt_gt
            break
    
    if rho > 0:
        theta = (s - 1.0) / rho
    else:
        theta = np.min(y) - 1.0 / n
    
    return np.maximum(y - theta, 0.0)


class Solver:
    def __init__(self):
        dummy = np.array([1.0, 2.0, 0.5], dtype=np.float64)
        _solve_proj(dummy)
    
    def solve(self, problem: dict[str, Any], **kwargs) -> Any:
        y = np.asarray(problem.get("y"), dtype=np.float64)
        x = _solve_proj(y)
        return {"solution": x}
--- End Solver ---
Running performance test...
============================= test session starts ==============================
platform linux -- Python 3.12.13, pytest-9.0.2, pluggy-1.6.0
rootdir: /tests
plugins: anyio-4.13.0, jaxtyping-0.3.9
collected 3 items

../tests/test_outputs.py .
--- Performance Summary ---
Validity: True
Total Baseline Time: 6.5014s
Total Solver Time:   2.7188s
Raw Speedup:         2.3913 x
Final Reward (Score): 2.3913
---------------------------
..

==================================== PASSES ====================================
=========================== short test summary info ============================
PASSED ../tests/test_outputs.py::test_solver_exists
PASSED ../tests/test_outputs.py::test_solver_validity
PASSED ../tests/test_outputs.py::test_solver_speedup
======================== 3 passed in 258.11s (0:04:18) =========================
