OverviewCode › R129
Code · blind round

R129 · Heap sort sifting the maximum to the back

blind round 7/11 local models answered

Every answer below carries the name of the model that wrote it. Blind refers to the scoring: the review was done without knowing which model produced which answer — the published result names them.

2 of the 11 local models delivered nothing through our test harness in this round — for reasons that lie with our setup, not with the models. Those cards are marked DNF like any other, but they are not evidence about those models — the reason is noted on the card itself.

Show task
Create ONE self-contained HTML file (STRICT LIMIT: max 7000 characters in total — this is a budget on characters, not on lines, so removing line breaks does not help) that animates heap sort on a <canvas>: around 80 vertical bars of random heights, first building a max-heap with visible sift-down swaps, then repeatedly swapping the root to the shrinking back of the array, marking the sorted tail in a distinct color and highlighting the elements involved in the current sift. Animate a few steps per frame. Show the number of swaps so far. Smooth requestAnimationFrame animation, NO user input, starts immediately and keeps running (restart with a fresh random instance when finished). No external libraries, no comments needed. Output ONLY the HTML file content, nothing else.

The answers

Local models (Brain cluster) — identical prompt, shuffled order (the sequence is not a ranking)
qwen3-coder:30bERRBLANKLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Heap Sort Visualization</title>
    <style>
        body { background: #111; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; font-family: monospace; color: white; }
        #controls { position: absolute; top: 20px; left: 50%; transform: translateX(-50%); padding: 10px; background: rgba(0, 0, 0, 0.7); border-radius: 5px; color: white; }
        canvas { border: 1px solid #333; background: #222; }
    </style>
</head>
<body>

<div id="controls">Swaps: <span id="swapCount">0</span></div>
<canvas id="heapCanvas"></canvas>

<script>
    const canvas = document.getElementById('heapCanvas');
    const ctx = canvas.getContext('2d');
    const N = 80;
    let bars = [];
    let swapCount = 0;
    let stepIndex = 0;
    let animationState = 'INITIALIZING'; // States: 'BUILDING', 'SORTING', 'FINISHED'
    let animationFrameId = null;

    canvas.width = 900;
    canvas.height = 400;
    const BAR_WIDTH = canvas.width / N;

    function initializeBars() {
        bars = Array(N).fill(0).map(() => Math.floor(Math.random() * 30) + 1);
        swapCount = 0;
        stepIndex = 0;
        document.getElementById('swapCount').textContent = '0';
    }

    function drawBars(highlight = [], swap = []) {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        for (let i = 0; i < N; i++) {
            const height = bars[i] * 4; // Scale factor for visibility
            let color = '#4CAF50';

            if (swap.includes(i)) {
                color = '#FFEB3B'; // Highlighted element
            } else if (highlight.includes(i)) {
                // Sorted tail area or current heap boundary
                color = '#2196F3'; 
            } else if (i === 0 || i === N - 1) {
                 color = '#555'; // Borders
            }

            ctx.fillStyle = color;
            ctx.fillRect(i * BAR_WIDTH, canvas.height - height, BAR_WIDTH - 2, height);
        }
    }

    // ----- Heap Sort Logic (State Machine) -----

    function siftDown(arr, startIdx, endBound) {
        let parent = startIdx;
        let currentChild = startIdx + 1;

        while (currentChild <= endBound) {
            let left = 2 * Math.floor((currentChild - startIdx) / 2) + startIdx;
            let right = 2 * floor((currentChild - startIdx) / 2) + 1 + startIdx;
            let largest = currentChild;

            if (left <= endBound && arr[left] > arr[largest]) {
                largest = left;
            }
            if (right <= endBound && arr[right] > arr[largest]) {
                largest = right;
            }

            if (largest !== currentChild) {
                swap(arr, currentChild, largest);
                currentChild = largest;
            } else {
                break;
            }
        }
    }

    function heapify(arr, startIdx, endBound) {
        let parent = Math.floor((startIdx + endBound) / 2) - 1;
        for (let i = Math.floor((startIdx + endBound) / 2) - 1; i >= startIdx; --i) {
            siftDown(arr, i, endBound);
        }
    }

    function swap(arr, i, j) {
        [arr[i], arr[j]] = [arr[j], arr[i]];
        swapCount++;
        return { i: i, j: j };
    }

    // Animation Steps Storage
    let animationSteps = []; 
    
    function captureStep(currentArray, highlightIndices, swapPair) {
         animationSteps.push({
            array: [...currentArray],
            highlight: [...highlightIndices],
            swap: swapPair || [] 
        });
    }

    // Phase 1: Build Heap
    function buildHeapAnimation() {
        const arr = [...bars];
        let steps = [];
        for (let i = Math.floor(N / 2) - 1; i >= 0; --i) {
            steps.push({ array: [...arr], highlight: [i], swap: [] }); // Initial state before siftDown
            siftDown(arr, i, N - 1);

            // Capture the step after sifting down completes (swaps are handled inside siftDown/swap calls)
             steps.push({ array: [...arr], highlight: [], swap: [] }); 
        }
        return steps;
    }


    // Phase 2: Sorting and Heapify Steps
    function sortHeapAnimation() {
        let arr = [...bars];
        let steps = [];
        const maxHeapSize = N - 1;

        for (let i = N - 1; i > 0; --i) {
            // Swap root (arr[0]) with current end element (arr[i])
            let swapPair = swap(arr, 0, i);
            steps.push({ array: [...arr], highlight: [i], swap: swapPair }); // Mark the sorted element

            // Restore heap property on remaining elements (heap size shrinks by 1)
            siftDown(arr, 0, i - 1);
             steps.push({ array: [...arr], highlight: [], swap: [] }); // Capture after sifting down
        }
        return steps;
    }

    function setupAnimation() {
        animationSteps = [];
        // 1. Build Phase (Max-Heap)
        let buildSteps = buildHeapAnimation();
        animationSteps.push(...buildSteps);

        // Reset state for sorting phase visualization
        bars = [...arrays[...animationSteps.length - 1].array];
        
        // 2. Sort Phase
        let sortSteps = [];
        sortSteps.push({ array: [...bars], highlight: [], swap: [] }); // Initial view before first sort step
        
        for (let i = N - 1; i > 0; --i) {
            // Swap root with arr[i]
            let currentArr = [...bars];
            let tempSwapArray = currentArr;
            tempSwapArray[0] = bars[i];
            tempSwapArray[i] = bars[0];

            swapCount++;
            const swapPair = { i: 0, j: i };
            sortSteps.push({ array: [...currentArr], highlight: [i], swap: swapPair }); 
            
            // Simulate the swap on the main state array for subsequent steps
            let tempBars = [...bars];
            [tempBars[0], tempBars[i]] = [tempBars[i], tempBars[0]];
            bars = tempBars;

            // Sift down on the remaining i-1 elements
             siftDown(bars, 0, i - 1);
             sortSteps.push({ array: [...bars], highlight: [], swap: [] }); 
        }
        animationSteps.push(...sortSteps);
    }

    // --- Main Animation Loop ---

    function animate() {
        if (!animationSteps || stepIndex >= animationSteps.length) {
            animationState = 'FINISHED';
            drawBars([]); // Final draw
            document.getElementById('swapCount').textContent = swapCount;
            return; 
        }

        const currentStep = animationSteps[stepIndex];
        
        // Update global state for the next step's drawing reference
        bars = [...currentStep.array];

        // Draw based on stored steps
        drawBars(currentStep.highlight, currentStep.swap);

        stepIndex++;
        animationFrameId = requestAnimationFrame(animate);
    }

    function startAnimationCycle() {
        if (animationFrameId) {
            cancelAnimationFrame(animationFrameId);
        }

        // Reset state and capture all steps for the new run
        setupAnimation(); 
        stepIndex = 0;
        swapCount = 0;
        document.getElementById('swapCount').textContent = '0';
        animationState = 'RUNNING';
        animate();
    }

    // Initialization sequence setup (since we cannot use user input)
    let arrays = [];
    function initialSetup() {
        initializeBars(); // Setup first random array for the first run visualization
        arrays.push(bars); 
        startAnimationCycle();
    }

    initialSetup();
</script>
</body>
</html>
```
qwen3.5:9bSTATFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Heap Sort Visualization</title>
    <style>
        body { margin: 0; display: flex; justify-content: center; align-items: center; background-color: #111; color: white; font-family: monospace; }
        canvas { border: 1px solid #333; background-color: #222; }
    </style>
</head>
<body>
    <canvas id="heapCanvas" width="800" height="400"></canvas>
    <script>
        const C = document.getElementById('heapCanvas');
        const CTX = C.getContext('2d');

        let A;
        let N, W, H;
        let swapCount = 0;
        let state = 'INIT'; // INIT, BUILD_HEAP, SORTING, COMPLETE
        let heapSize = 0;
        let currentSwapIndices = [];

        const BAR_WIDTH = 8;
        const PADDING = 10;

        function initialize(arr) {
            A = arr;
            N = A.length;
            W = C.width - (PADDING * 2);
            H = C.height;
            heapSize = N;
            swapCount = 0;
            state = 'BUILD_HEAP';
            currentSwapIndices = [];
        }

        function draw() {
            CTX.clearRect(0, 0, C.width, C.height);

            for (let i = 0; i < N; i++) {
                const x1 = PADDING + i * (BAR_WIDTH + 2);
                const x2 = PADDING + i * (BAR_WIDTH + 2) + BAR_WIDTH;
                const height = A[i] * (H / Math.max(...A));

                CTX.fillStyle = '#007bff'; // Default color
                if (i === 0 && state === 'BUILD_HEAP') {
                    CTX.fillStyle = '#ffc107'; // Root highlight during build
                } else if (state === 'SORTING' && i >= N - heapSize) {
                    // Sorted tail
                    CTX.fillStyle = '#28a745'; 
                } else if (currentSwapIndices.includes(i)) {
                    // Currently swapping or involved in sift down
                    CTX.fillStyle = '#ff6b6b'; 
                }

                CTX.fillRect(x1, H - height, BAR_WIDTH, height);
            }
        }

        function swap(i, j) {
            if (i === j) return;
            [A[i], A[j]] = [A[j], A[i]];
            currentSwapIndices.push(i, j);
            swapCount++;
        }

        // Max-Heapify implementation
        function siftDown(i, end) {
            let largest = i;
            const left = 2 * i + 1;
            const right = 2 * i + 2;

            if (left <= end && A[left] > A[largest]) {
                largest = left;
            }
            if (right <= end && A[right] > A[largest]) {
                largest = right;
            }

            if (largest !== i) {
                swap(i, largest);
                // Recurse only if we are still within the heap bounds
                siftDown(largest, end); 
            }
        }

        function buildHeap() {
            for (let i = Math.floor(N / 2) - 1; i >= 0; i--) {
                if (state === 'BUILD_HEAP') {
                    siftDown(i, N - 1); 
                    // Note: We don't reset currentSwapIndices here as the animation loop handles that.
                }
            }
            state = 'SORTING';
        }

        function heapSort() {
            for (let i = N - 1; i > 0; i -= 1) {
                // Swap A[i] (the largest element found so far) with the root A[0]
                swap(0, i); 
                
                // The heap size shrinks by one, meaning we sort up to index i-1.
                const newHeapSize = i;

                if (newHeapSize > 0) {
                     siftDown(0, newHeapSize - 1);
                }
            }
            state = 'COMPLETE';
        }


        async function animateStep() {
            // Clear highlights after step completes
            currentSwapIndices = [];
            draw();

            if (state === 'BUILD_HEAP') {
                buildHeap();
                setTimeout(() => requestAnimationFrame(animateStep), 100);
                return;
            }

            if (state === 'SORTING') {
                // We use setTimeout/Promise structure to simulate asynchronous steps
                await new Promise(resolve => setTimeout(resolve, 40)); 
                heapSort();
                setTimeout(() => requestAnimationFrame(animateStep), 10);
                return;
            }

            if (state === 'COMPLETE') {
                // Loop restart logic: Wait a moment, then reset the entire process.
                await new Promise(resolve => setTimeout(resolve, 200));
                const initialArray = Array.from({ length: N }, () => Math.floor(Math.random() * 30) + 1);
                initialize(initialArray);
            }
        }

        // --- Setup ---
        function setupInitialState() {
             N = 80;
             A = Array.from({ length: N }, () => Math.floor(Math.random() * 30) + 1);
             initialize(A);
             animateStep();
        }

        setupInitialState();
    </script>
</body>
</html>
```
llama3.1:8bSTATFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Heap Sort Animation</title>
    <style>
        body {
            font-family: monospace;
            margin: 0;
            padding: 0;
        }
        #canvas {
            border: 1px solid black;
        }
        .highlighted-bar {
            background-color: yellow;
        }
    </style>
</head>
<body>
<canvas id="canvas" width="800" height="600"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 800;
canvas.height = 600;

let heap, swaps = 0;
function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    for (let i = 0; i < heap.length; ++i) {
        let h = Math.floor(heap[i] * (canvas.height - 10) / 100);
        ctx.fillStyle = 'blue';
        ctx.fillRect(i * (canvas.width - 1) / 80, canvas.height - h, (canvas.width - 1) / 80, h);
    }
    ctx.font = '24px monospace';
    ctx.textAlign = 'left';
    ctx.textBaseline = 'top';
    ctx.fillStyle = 'black';
    ctx.fillText(`Swaps: ${swaps}`, 10, 0);
}

function buildMaxHeap() {
    for (let i = Math.floor(heap.length / 2) - 1; i >= 0; --i) {
        let parent = i;
        let child = 2 * parent + 1;
        while (child < heap.length) {
            if (heap[child] > heap[parent]) {
                [heap[child], heap[parent]] = [heap[parent], heap[child]];
                ctx.fillStyle = 'red';
                ctx.fillRect(parent * (canvas.width - 1) / 80, canvas.height - Math.floor(heap[i] * (canvas.height - 10) / 100), (canvas.width - 1) / 80, Math.floor(heap[i++] * (canvas.height - 10) / 100));
                draw();
                requestAnimationFrame(buildMaxHeap);
                return;
            }
            if (child + 1 < heap.length && heap[child + 1] > heap[child]) child++;
            parent = child;
            child *= 2 + 1;
        }
    }
}

let step = 0, nSwaps = 0;
function heapSort() {
    buildMaxHeap();
    while (heap.length) {
        let root = heap.shift();
        ctx.fillStyle = 'green';
        ctx.fillRect(0, canvas.height - Math.floor(root * (canvas.height - 10) / 100), (canvas.width - 1) / 80, Math.floor(root * (canvas.height - 10) / 100));
        draw();
        requestAnimationFrame(heapSort);
    }
}

function generateRandomHeap() {
    heap = Array(80).fill().map(() => Math.random() * 100);
    swaps = nSwaps = 0;
}

generateRandomHeap();

heapSort();

</script>
</body>
</html>
```
qwen3:14bERRBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Heap Sort Animation</title>
    <style>
        body { background: #111; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; }
        canvas { border: 1px solid #333; background: #222; }
    </style>
</head>
<body>
<canvas id="heapCanvas" width="800" height="400"></canvas>

<script>
const canvas = document.getElementById('heapCanvas');
const ctx = canvas.getContext('2d');

let arr;
let N = 80;
let max_val = 400;
let swapCount = 0;
let state = 'INIT'; // INIT, BUILDING_HEAP, SORTING, FINISHED
let stepDelay = 50; // Milliseconds per frame update

// State tracking for animation
let initialArray = [];
let heapState = {
    isBuilding: false,
    currentSwap: null, // [i, j]
    siftPath: [],     // Indices involved in current sift-down
    heapStart: N - 1   // Index up to which the heap is active
};

function generateRandomArray() {
    arr = [];
    for (let i = 0; i < N; i++) {
        arr.push(Math.floor(Math.random() * max_val) + 5);
    }
}

function drawBars() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    const barWidth = (canvas.width - 20) / N;
    let x_offset = 10;

    for (let i = 0; i < N; i++) {
        ctx.fillStyle = '#4CAF50'; // Default green
        ctx.fillRect(x_offset + i * barWidth, 0, barWidth - 2, arr[i]);
    }

    // Highlight sorted tail (right side)
    for (let i = N - 1; i >= Math.max(N - 1, heapState.heapStart + 1); i--) {
        ctx.fillStyle = '#8B0000'; // Dark Red for sorted
        const barWidth = (canvas.width - 20) / N;
        ctx.fillRect(x_offset + i * barWidth, 0, barWidth - 2, arr[i]);
    }

    // Highlight current swap/sift path
    if (heapState.currentSwap) {
        const [i, j] = heapState.currentSwap;
        const barWidth = (canvas.width - 20) / N;
        ctx.fillStyle = '#FFD700'; // Gold highlight for swap
        ctx.fillRect(x_offset + i * barWidth, 0, barWidth - 2, arr[i]);
        ctx.fillRect(x_offset + j * barWidth, 0, barWidth - 2, arr[j]);
    }

    // Highlight the element being sifted down (the hole)
    if (heapState.siftPath.length > 0 && heapState.siftPath[heapState.siftPath.length - 1] < N) {
        const lastIndex = heapState.siftPath[heapState.siftPath.length - 1];
        const barWidth = (canvas.width - 20) / N;
        ctx.fillStyle = '#FFA500'; // Orange for current sift point
        ctx.fillRect(x_offset + lastIndex * barWidth, 0, barWidth - 2, arr[lastIndex]);
    }

    // Display swap count
    ctx.fillStyle = '#FFF';
    ctx.font = '16px Arial';
    ctx.fillText('Swaps: ' + swapCount, 10, 30);
}


function heapify(i) {
    let largest = i;
    const left = 2 * i + 1;
    const right = 2 * i + 2;

    if (left < N && arr[left] > arr[largest]) {
        largest = left;
    }
    if (right < N && arr[right] > arr[largest]) {
        largest = right;
    }
    return largest; // Returns the index of the true largest child/self
}

function siftDown(start_idx) {
    let current = start_idx;
    let parent = Math.floor((start_idx - 1) / 2);

    while (current < N) {
        // Find the child with the maximum value among left and right
        let largest = current;
        const left = 2 * current + 1;
        const right = 2 * current + 2;

        if (left < N && arr[left] > arr[largest]) {
            largest = left;
        }
        if (right < N && arr[right] > arr[largest]) {
            largest = right;
        }

        if (largest !== current) {
            // Swap and record the move for animation
            heapState.currentSwap = [current, largest];
            swapCount++;
            const temp = arr[current];
            arr[current] = arr[largest];
            arr[largest] = temp;

            // Clear path tracking after a swap to prevent stale highlights
            if (heapState.siftPath.length > 0) {
                heapState.siftPath = [];
            }
            
            current = largest;
        } else {
            break; // Heap property satisfied
        }
    }
}

function buildMaxHeap() {
    // Start from the last non-leaf node and sift down up to N-1
    for (let i = Math.floor(N / 2) - 1; i >= 0; i--) {
        siftDown(i);
    }
    heapState.isBuilding = false;
}

function sortArray() {
    // Main Heap Sort loop: repeatedly swap root (max element) to the end
    for (let i = N - 1; i > 0; i--) {
        const currentMaxIndex = 0; // Root is always index 0 before swaps
        
        if (i !== N - 1) {
            // 1. Swap root (max element) with the last unsorted element (i)
            heapState.currentSwap = [currentMaxIndex, i];
            swapCount++;

            const temp = arr[currentMaxIndex];
            arr[currentMaxIndex] = arr[i];
            arr[i] = temp;
        } else {
             // First iteration swap (0 <-> N-1) is handled above. 
             // Subsequent swaps happen within the heapify/siftDown process below.
        }

        // The effective size of the heap decreases by 1 each time
        heapState.heapStart = i;
        
        // 2. Restore the max-heap property on the remaining elements (0 to i)
        if (i > 0) {
            siftDown(0);
        }
    }

    state = 'FINISHED';
}


function animate() {
    drawBars();

    if (state === 'INIT') {
        generateRandomArray();
        state = 'BUILDING_HEAP';
        // Reset state tracking variables for the start of the animation
        heapState.currentSwap = null; 
        heapState.siftPath = [];
        heapState.heapStart = N - 1;
    }

    if (state === 'BUILDING_HEAP') {
        buildMaxHeap();
        // After building, transition to sorting phase immediately for continuous animation flow
        setTimeout(() => {
            sortArray();
            state = 'SORTING'; // State is now implicitly handled by sortArray's logic
        }, stepDelay); 

    } else if (state === 'SORTING') {
        // The actual state change happens within the loop of sortArray, but we need to trigger the next iteration.
        // Since sortArray completes all steps, we simply wait for it to finish its visual cycle.
    }


    if (state === 'FINISHED') {
        setTimeout(() => {
            alert("Heap Sort Complete! Restarting...");
            window.requestAnimationFrame(animate); // Trigger restart loop
            state = 'INIT'; // Reset state machine
        }, 1500); // Wait 1.5 seconds before restarting
    } else {
        // Use a delayed requestAnimationFrame to control the animation speed (stepDelay)
        setTimeout(() => {
            window.requestAnimationFrame(animate);
        }, stepDelay);
    }
}

// Initial call to start the animation loop
window.onload = () => {
    window.requestAnimationFrame(animate);
};

</script>
</body>
</html>
```
deepseek-r1:14bERRBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html><body style="background:#000;margin:0;display:flex;justify-content:center;height:100vh">
<canvas id=c width=800 height=240></canvas>
<script>
const c=document.getElementById('c'), ctx=c.getContext('2d'); 
let h=[],n=80,a=Array.from({length:n},()=>Math.random()*256|0),s=0,step=0,timer;
function draw(){for(let i=0;i<n;i++)ctx.fillStyle=`rgba(160,${i<step?32:0},${i<step?32:0})`,ctx.fillRect(i*9+3, h[i],5,h[n-1]);}
function swap(i,j){let t=h[i];h[i]=h[j];h[j]=t;if(step){draw();requestAnimationFrame(_=>swapDone(i,j));}else draw();}
function swapDone(i,j){step++;document.getElementById('c').style.color='white';ctx.fillStyle=`rgba(255,0,0,.3)`;draw();console.log(step);}
function heapify(n,i){{let j=i,l=2*i+1>r=n-1?n-1:r,l=r;if(j>l)swapDone(i,j);else if(h[j]<h[l])swap(j,l),j=l,l=2*l+1>r?r:l;}}
function animateHeapify(){{if(step < n)swap(step,0),step++;}else{animateExtract();}}}
function animateExtract(){while(step<n-1){let i=0,j=n-1-step;swap(i,j);heapify(j,i);}}
c.addEventListener('click',_=>{h=a.map(_=>Math.random()*256|0);s=0;step=0;s.clearRect(0,0,c.width,c.height);draw();})
c.style.color='white';ctx.fillStyle=`rgba(160,32,32)`;draw();
</script>
</body></html>
```
qwen3:8bharness
No answer reached us (ERR) — and the reason lies with our setup, not with the model: reasoning consumed the entire token budget and the answer stayed empty; the gateway rejects budgets above 3000 tokens Counted as a did-not-finish, but it is not evidence about this model.
gemma4:26bharness
No answer reached us (ERR) — and the reason lies with our setup, not with the model: reasoning consumed the entire token budget (3 min 28 s, zero characters of answer); larger budgets are refused by the gateway Counted as a did-not-finish, but it is not evidence about this model.
mistral-small:24bERRBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Heap Sort Animation</title>
<style>
body { margin: 0; overflow: hidden; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f0f0f0; }
canvas { border: 1px solid black; }
</style>
</head>
<body>
<canvas id="heapSortCanvas" width="800" height="600"></canvas>
<script>
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
let canvas = document.getById('heapSortCanvas');
let ctx = canvas.getContext('2d');
let width = canvas.width;
let height = canvas.height;
let bars = Array.from({ length: 80 }, () => randomInt(50, height - 50));
let swaps = 0;

function drawBars() {
ctx.clearRect(0, 0, width, height);
for (let i = 0; i < bars.length; i++) {
let barHeight = bars[i];
let x = i * 10 + 20;
let y = height - barHeight;
let color = 'blue';
if (i >= sortedLength) color = 'green';

ctx.fillStyle = color;
ctx.fillRect(x, y, 8, barHeight);
}
}

function heapify(n, i) {
while (true) {
let largest = i;
let left = 2 * i + 1;
let right = 2 * i + 2;
if (left < n && bars[left] > bars[largest]) largest = left;
if (right < n && bars[right] > bars[largest]) largest = right;

if (largest === i) break;
swap(i, largest);
i = largest;
}
}

function swap(i, j) {
let temp = bars[i];
bars[i] = bars[j];
bars[j] = temp;
swaps++;
drawBars();
requestAnimationFrame(() => { ctx.fillText(`Swaps: ${swaps}`, 10, 20); });
}

function heapSort() {
for (let i = Math.floor(bars.length / 2) - 1; i >= 0; i--) heapify(bars.length, i);

for (let i = bars.length - 1; i > 0; i--) {
swap(0, i);
heapify(i, 0);
}
}

function animateHeapSort() {
if (frame < frames.length) { drawBars(); requestAnimationFrame(animateHeapSort); }
else { heapSort(); swaps = 0; bars = Array.from({ length: 80 }, () => randomInt(50, height - 50)); setTimeout(() => animateHeapSort(), 1000); }
}

let frame = 0;
const frames = [];
heapSort();
animateHeapSort();
</script>
```
No usable answer reached the harness (ERR). Counted as a did-not-finish.
deepseek-r1:32bSTATMINIFIEDFORMAT
Show code
```html
<!DOCTYPE html>
<html><head><style>body{margin:0;background:#f0f0f0;display:flex;justify-content:center;align-items:center;height:100%;min-height:100vh;font-family:sans-serif}.canvas-container{background:white;padding:20px;border-radius:8px;box-shadow:0 0 10px rgba(0,0,0,.1)}.swap-count{position:absolute;top:10px;left:10px;color:#333}</style></head><body>
<canvas class="canvas-container"></canvas>
<div class="swap-count">Swaps: 0</div>
<script>
const canvas=document.querySelector('canvas'),ctx=canvas.getContext('2d');let w=80,h=640,barWidth=3,space=1;canvas.width=w*(barWidth+space)+50;canvas.height=h;
class HeapSortVisualizer{constructor(){this.data=this.generateRandom();this.n=80;this.state='heap';this.current=0;this.swaps=0;this.heapifySteps=[];this.sorting=false;this.siftIndex=-1;this.animationComplete=false}
generateRandom(){return Array.from({length:80},()=>Math.random())}drawBar(index,height,color){let x=index*(barWidth+space)+25,y=h-height;ctx.fillStyle=color;ctx.fillRect(x,y,barWidth,height)}
animate(){requestAnimationFrame(()=>{if(this.animationComplete)return;this.draw();this.performStep()})}
performStep(){if(!this.sorting&&this.state==='heap'){this.buildHeap()}else if(this.state==='sorting')this.extractMax()}
buildHeap(){for(let i=Math.floor(this.n/2)-1;i>=0;i--){let index=i;while(true){let left=2*index+1,right=2*index+2,largest=index;if(left<this.n&&this.data[left]>this.data[largest])largest=left;if(right<this.n&&this.data[right]>this.data[largest])largest=right;if(largest!==index){[this.data[index],this.data[largest]]=swap(this.data[index],this.data[largest]);this.swaps++;this.siftIndex=index;setTimeout(()=>{this.siftIndex=-1},200);index=largest}else break}}}
extractMax(){if(this.n<=0){this.animationComplete=true;return}let lastIndex=this.n-1;[this.data[0],this.data[lastIndex]]=swap(this.data[0],this.data[lastIndex]);this.swaps++;this.n--;this.siftDown(0)}
siftDown(index){while(true){let left=2*index+1,right=2*index+2,largest=index;if(left<this.n&&this.data[left]>this.data[largest])largest=left;if(right<this.n&&this.data[right]>this.data[largest])largest=right;if(largest!==index){[this.data[index],this.data[largest]]=swap(this.data[index],this.data[largest]);this.swaps++;this.siftIndex=index;setTimeout(()=>{this.siftIndex=-1},200);index=largest}else break}}
draw(){ctx.clearRect(0,0,canvas.width,canvas.height);for(let i=0;i<80;i++){let color='#3498db';if(i>=80-this.n)color='#2ecc71';if(this.siftIndex===i||this.siftIndex===Math.floor((i-1)/2))color='#f1c40f';this.drawBar(i,this.data[i]*h,color)}document.querySelector('.swap-count').textContent=`Swaps: ${this.swaps}`}}
let visualizer=new HeapSortVisualizer();visualizer.animate();setTimeout(() => {if(visualizer.animationComplete)visualizer=new HeapSortVisualizer(),visualizer.animate()},10)
function swap(a,b){return [b,a]
}
</script></body></html>
```
No usable answer reached the harness (ERR). Counted as a did-not-finish.
Outside the Brain cluster — same task, same character budget, collected through their own tooling (response times not comparable)
Claude Opus 5frontier referenceOK
Show code
<!doctype html>
<meta charset="utf-8">
<title>Heap Sort</title>
<style>html,body{margin:0;height:100%;background:#0b0f14;overflow:hidden}canvas{display:block}</style>
<canvas id=c></canvas>
<script>
const c=document.getElementById('c'),x=c.getContext('2d');
let W,H;function fit(){W=c.width=innerWidth;H=c.height=innerHeight}fit();onresize=fit;
const N=80;let a,swaps,phase,hi,end,sift,sorted,hl,hold;
function init(){a=[];for(let i=0;i<N;i++)a.push(.04+Math.random()*.96);swaps=0;phase='build';hi=(N>>1)-1;end=N-1;sift=null;sorted=N;hl=[];hold=0}
function sw(i,j){const t=a[i];a[i]=a[j];a[j]=t;swaps++}
function step(){
 if(hold>0){hold--;if(hold===0)init();return}
 if(sift){const e=sift.end,i=sift.i,l=2*i+1,r=l+1;let m=i;
  if(l<e&&a[l]>a[m])m=l;
  if(r<e&&a[r]>a[m])m=r;
  hl=[i];if(l<e)hl.push(l);if(r<e)hl.push(r);
  if(m!==i){sw(i,m);sift.i=m}else sift=null;
  return}
 if(phase==='build'){if(hi>=0){sift={i:hi,end:N};hl=[hi];hi--}else{phase='sort';end=N-1}return}
 if(end>0){sw(0,end);sorted=end;hl=[0,end];sift={i:0,end:end};end--}
 else{sorted=0;hl=[];hold=70}
}
function draw(){
 x.fillStyle='#0b0f14';x.fillRect(0,0,W,H);
 const pad=24,top=66,bw=(W-2*pad)/N,mh=Math.max(20,H-top-pad);
 for(let i=0;i<N;i++){
  const h=a[i]*mh,y=H-pad-h;
  x.fillStyle=hl.indexOf(i)>=0?'#ff8a3d':(i>=sorted?'#37d67a':'#3aa0d8');
  x.fillRect(pad+i*bw+.5,y,Math.max(1,bw-1.5),h);
 }
 x.fillStyle='#e6edf3';x.font='600 20px system-ui,-apple-system,sans-serif';
 x.fillText('Heap Sort — swaps: '+swaps,pad,34);
 x.font='13px system-ui,-apple-system,sans-serif';x.fillStyle='#8b9aa8';
 x.fillText(hold>0?'sorted — restarting with a new random array':(phase==='build'?'phase 1: building max-heap (sift-down)':'phase 2: swap root to shrinking back, then sift down'),pad,54);
}
function loop(){for(let k=0;k<3;k++)step();draw();requestAnimationFrame(loop)}
init();loop();
</script>
Claude Sonnet 5frontier referenceOK
Show code
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>Heap Sort Visualization</title>
<style>
html,body{margin:0;padding:0;background:#111;overflow:hidden;height:100%}
canvas{display:block}
#info{position:fixed;top:10px;left:10px;color:#eee;font:16px monospace;text-shadow:0 0 4px #000}
</style></head>
<body>
<div id="info">Swaps: 0</div>
<canvas id="c"></canvas>
<script>
const cv=document.getElementById('c'),ctx=cv.getContext('2d'),info=document.getElementById('info');
function resize(){cv.width=innerWidth;cv.height=innerHeight;}
resize();addEventListener('resize',resize);

let N=80,arr,swaps,gen,ev,sortedFrom,done,frame=0;

function rnd(a){for(let i=0;i<N;i++)a[i]=20+Math.random()*260;return a;}
function swapA(a,x,y){const t=a[x];a[x]=a[y];a[y]=t;}

function* siftDown(a,i,n){
 while(true){
  let l=2*i+1,r=2*i+2,largest=i;
  yield {t:'cmp',i,l,r};
  if(l<n&&a[l]>a[largest])largest=l;
  if(r<n&&a[r]>a[largest])largest=r;
  if(largest===i)break;
  swapA(a,i,largest);swaps++;
  yield {t:'swp',a:i,b:largest};
  i=largest;
 }
}

function* heapSort(a){
 let n=a.length;
 for(let i=(n>>1)-1;i>=0;i--) yield* siftDown(a,i,n);
 for(let end=n-1;end>0;end--){
  swapA(a,0,end);swaps++;
  sortedFrom=end;
  yield {t:'swp',a:0,b:end};
  yield* siftDown(a,0,end);
 }
 sortedFrom=0;
}

function reset(){
 arr=rnd(new Array(N));
 swaps=0;sortedFrom=N;done=false;
 gen=heapSort(arr);
 ev=null;
 step();
}

function step(){
 const r=gen.next();
 if(r.done){done=true;ev=null;}
 else ev=r.value;
}

function draw(){
 ctx.fillStyle='#111';
 ctx.fillRect(0,0,cv.width,cv.height);
 const w=cv.width/N;
 const maxH=300;
 const scale=(cv.height*0.8)/maxH;
 let hi=new Set(),root=-1;
 if(ev){
  if(ev.t==='cmp'){hi.add(ev.l);hi.add(ev.r);root=ev.i;}
  else if(ev.t==='swp'){hi.add(ev.a);hi.add(ev.b);}
 }
 for(let i=0;i<N;i++){
  const h=arr[i]*scale;
  const x=i*w;
  const y=cv.height-h-20;
  let color;
  if(i>=sortedFrom) color='#2ecc71';
  else if(i===root) color='#e74c3c';
  else if(hi.has(i)) color='#f1c40f';
  else color='#3498db';
  ctx.fillStyle=color;
  ctx.fillRect(x+1,y,w-2,h);
 }
 info.textContent='Swaps: '+swaps+(done?' (sorted! restarting...)':'');
}

reset();
function loop(){
 if(!done){
  for(let k=0;k<3&&!done;k++) step();
 } else {
  frame++;
  if(frame>60){reset();frame=0;}
 }
 draw();
 requestAnimationFrame(loop);
}
loop();
</script>
</body></html>
Claude Fable 5frontier referenceOK
Show code
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Heap Sort Visualization</title>
<style>
html,body{margin:0;height:100%;background:#0d1117;overflow:hidden}
canvas{display:block}
</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
const cv=document.getElementById("c"),ctx=cv.getContext("2d");
let W,H;
function resize(){W=cv.width=innerWidth;H=cv.height=innerHeight}
addEventListener("resize",resize);resize();
const N=80,STEPS=3;
let a,swaps,sortedFrom,hl,phase,gen,pause;
function reset(){
a=Array.from({length:N},()=>0.05+Math.random()*0.95);
swaps=0;sortedFrom=N;hl=[];phase="building max-heap";gen=run();pause=0;
}
function*sift(i,m){
for(;;){
let l=2*i+1,r=l+1,b=i;
if(l<m&&a[l]>a[b])b=l;
if(r<m&&a[r]>a[b])b=r;
hl=[i];
if(l<m)hl.push(l);
if(r<m)hl.push(r);
yield;
if(b===i)return;
[a[i],a[b]]=[a[b],a[i]];swaps++;hl=[i,b];
yield;
i=b;
}
}
function*run(){
for(let i=(N>>1)-1;i>=0;i--)yield*sift(i,N);
phase="extracting max";
for(let m=N-1;m>0;m--){
[a[0],a[m]]=[a[m],a[0]];swaps++;sortedFrom=m;hl=[0,m];
yield;
yield*sift(0,m);
}
sortedFrom=0;hl=[];phase="sorted";
}
function draw(){
ctx.fillStyle="#0d1117";ctx.fillRect(0,0,W,H);
const pad=20,bw=(W-2*pad)/N,top=64,bh=H-top-pad;
for(let i=0;i<N;i++){
let col=i>=sortedFrom?"#3fb950":"#2f81f7";
if(hl.includes(i))col="#f85149";
ctx.fillStyle=col;
const h=a[i]*bh;
ctx.fillRect(pad+i*bw+1,H-pad-h,Math.max(bw-2,1),h);
}
ctx.fillStyle="#e6edf3";ctx.font="16px monospace";
ctx.fillText("heap sort - "+phase,pad,28);
ctx.fillText("swaps: "+swaps,pad,50);
}
function tick(){
if(pause>0){
pause--;
if(pause===0)reset();
}else{
for(let k=0;k<STEPS;k++){
if(gen.next().done){pause=90;break}
}
}
draw();
requestAnimationFrame(tick);
}
reset();
requestAnimationFrame(tick);
</script>
</body>
</html>
Claude Haiku 4.5frontier referenceOKMINIFIED
Show code
<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>Heap Sort</title><style>body{margin:0;display:flex;align-items:center;justify-content:center;height:100vh;background:#1a1a1a;font-family:monospace}canvas{border:1px solid #666}</style></head><body><canvas id="c" width="800" height="500"></canvas><script>const c=document.getElementById('c');const ctx=c.getContext('2d');const n=80;let h=[],swaps=0,phase='build',heapSize=0,swapIdx=-1,steps=0;function setup(){h=[];for(let i=0;i<n;i++)h.push(Math.random());swaps=0;phase='build';heapSize=n;swapIdx=-1;steps=0;}function sift(i,s){while(true){let l=2*i+1,r=2*i+2,m=i;if(l<s&&h[l]>h[m])m=l;if(r<s&&h[r]>h[m])m=r;if(m===i)break;swapIdx=i*100+m;[h[i],h[m]]=[h[m],h[i]];swaps++;i=m;}}function step(){if(phase==='build'){for(let k=0;k<5;k++){if(steps>=n/2)break;let i=Math.floor(n/2)-1-steps;sift(i,n);steps++;}if(steps>=n/2)phase='sort';}else{for(let k=0;k<5;k++){if(heapSize<=1)break;swapIdx=heapSize-1;[h[0],h[heapSize-1]]=[h[heapSize-1],h[0]];swaps++;heapSize--;sift(0,heapSize);}if(heapSize<=1)setup();}}function draw(){ctx.fillStyle='#1a1a1a';ctx.fillRect(0,0,c.width,c.height);const w=c.width/n,maxH=Math.max(...h);for(let i=0;i<n;i++){const barH=h[i]*c.height/maxH;const x=i*w;let a=Math.floor(swapIdx/100),b=swapIdx%100;if(i>=heapSize)ctx.fillStyle='#0f0';else if(i===a||i===b)ctx.fillStyle='#f00';else ctx.fillStyle='#4a9eff';ctx.fillRect(x,c.height-barH,w-1,barH);}ctx.fillStyle='#0f0';ctx.font='14px monospace';ctx.fillText('Swaps: '+swaps,10,20);}function animate(){step();draw();requestAnimationFrame(animate);}setup();animate();</script></body></html>
Results at a glance— every model in this round with score, response time and status.

Who wrote what

ModelBlind scoreLatencyStatus
qwen3-coder:30b 33.7 sOK
qwen3.5:9b 59.4 sOK
llama3.1:8b 71.2 sOK
qwen3:14b 39.6 sOK
deepseek-r1:14b 34.7 sOK
qwen3:8b harness
gemma4:26b harness
mistral-small:24b 80.9 sOK
qwq:32b DNF
deepseek-r1:32b 60.4 sOK
command-r:35b DNF