OverviewCode › R153
Code · blind round

R153 · Binary min-heap with bubble-up and sink-down

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 a binary min-heap on a <canvas>, drawn as a proper tree layout of circular nodes labelled with their value connected by edges to their parent and children (not as array bars): repeatedly insert a new random value as a new leaf at the next open tree position and animate its bubble-up, swapping it with its parent step by step with a visible highlight and brief pause at each swap, as long as it is smaller than its parent, until the heap property holds again. After a few insertions, perform an extract-min: remove and clearly display the root value, move the last leaf into the root position, and animate its sink-down, swapping it with its smaller child step by step until the heap property holds again. Keep alternating insert phases and extract-min phases on the same persistent heap rather than rebuilding the whole structure each time, only resetting to a fresh empty heap once it has emptied out or grown very large. Show the total number of insert and extract-min operations performed 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.5:9bOKLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html><head><title>Heap Animation</title></head><body style="margin:0;overflow:hidden;"><canvas id="heapCanvas" width="800" height="600"></canvas><script>
    const canvas = document.getElementById('heapCanvas');
    const ctx = canvas.getContext('2d');

    let heap = [];
    let isAnimating = false;
    let animationState = {};

    const NODE_RADIUS = 15;
    const LEVEL_HEIGHT = 60;
    const MAX_NODES = 100;

    function getCoords(index) {
        if (index < 0 || index >= heap.length) return null;
        let i = index;
        let level = 0;
        while (i > 0 && i % 2 === 0) {
            i /= 2;
            level++;
        }
        let nodeIndexAtLevel = Math.floor(index / Math.pow(2, level));
        let x = (nodeIndexAtLevel - ((Math.pow(2, level)) - 1) / 2) * 80 + (canvas.width / 4);
        let y = LEVEL_HEIGHT * level;
        return { x: Math.max(50, Math.min(canvas.width - 50, x)), y: Math.max(NODE_RADIUS * 1.5, y) };
    }

    function drawHeap(currentSwapIndices = null) {
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        const nodesToDraw = heap.map((value, index) => ({ value, index }));

        // Draw edges and nodes based on the current state (including potential swaps)
        for (let i = 0; i < heap.length; i++) {
            const node = { value: heap[i], index: i };
            const coords = getCoords(i);

            if (!coords) continue;

            // Highlight if this is the current focus of animation
            let highlight = false;
            if (currentSwapIndices && (currentSwapIndices.includes(i))) {
                highlight = true;
            } else if (animationState.focusIndex === i) {
                highlight = true;
            }

            // Draw edges to parent and children
            const parentIndex = Math.floor((i - 1) / 2);
            if (parentIndex >= 0 && heap[parentIndex] !== undefined) {
                const pCoords = getCoords(parentIndex);
                ctx.beginPath();
                ctx.moveTo(pCoords.x, pCoords.y + NODE_RADIUS);
                ctx.lineTo(coords.x, coords.y - NODE_RADIUS);
                ctx.strokeStyle = '#aaa';
                ctx.lineWidth = 2;
                ctx.stroke();
            }

            const leftChildIndex = 2 * i + 1;
            if (leftChildIndex < heap.length) {
                const lCoords = getCoords(leftChildIndex);
                ctx.beginPath();
                ctx.moveTo(coords.x, coords.y + NODE_RADIUS);
                ctx.lineTo(lCoords.x, lCoords.y - NODE_RADIUS);
                ctx.strokeStyle = '#aaa';
                ctx.lineWidth = 2;
                ctx.stroke();
            }

            const rightChildIndex = 2 * i + 2;
            if (rightChildIndex < heap.length) {
                const rCoords = getCoords(rightChildIndex);
                ctx.beginPath();
                ctx.moveTo(coords.x, coords.y + NODE_RADIUS);
                ctx.lineTo(rCoords.x, rCoords.y - NODE_RADIUS);
                ctx.strokeStyle = '#aaa';
                ctx.lineWidth = 2;
                ctx.stroke();
            }

            // Draw node circle and label
            ctx.beginPath();
            ctx.arc(coords.x, coords.y, NODE_RADIUS, 0, Math.PI * 2);
            ctx.fillStyle = highlight ? '#ffeb3b' : '#4CAF50';
            ctx.fill();
            ctx.strokeStyle = 'black';
            ctx.lineWidth = 1;
            ctx.stroke();

            // Draw value text
            ctx.fillStyle = 'black';
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            ctx.fillText(heap[i], coords.x, coords.y);
        }
    }

    function swap(i, j) {
        if (i === j) return;
        [heap[i], heap[j]] = [heap[j], heap[i]];
    }

    // --- Heap Operations ---

    async function bubbleUp(currentIndex) {
        let i = currentIndex;
        const parentIndex = Math.floor((i - 1) / 2);

        while (i > 0 && heap[i] < heap[parentIndex]) {
            animationState.focusIndices = [i, parentIndex];
            drawHeap(animationState.focusIndices);
            await new Promise(resolve => setTimeout(resolve, 150)); // Pause at swap

            swap(i, parentIndex);
            i = parentIndex;
            const nextParentIndex = Math.floor((i - 1) / 2);
            animationState.focusIndices = [i, nextParentIndex];
            drawHeap(animationState.focusIndices);
            await new Promise(resolve => setTimeout(resolve, 150));

            if (nextParentIndex < 0) break; // Should not happen if i > 0 check passed
        }
    }

    async function sinkDown(currentIndex) {
        let i = currentIndex;
        const n = heap.length;

        while (true) {
            let leftChildIndex = 2 * i + 1;
            let rightChildIndex = 2 * i + 2;
            let smallest = i;

            // Find the smallest among parent, left, and right
            if (leftChildIndex < n && heap[leftChildIndex] < heap[smallest]) {
                smallest = leftChildIndex;
            }
            if (rightChildIndex < n && heap[rightChildIndex] < heap[smallest]) {
                smallest = rightChildIndex;
            }

            if (smallest === i) break; // Heap property restored

            // Animate swap preparation
            animationState.focusIndices = [i, smallest];
            drawHeap(animationState.focusIndices);
            await new Promise(resolve => setTimeout(resolve, 150));

            // Perform swap and animation
            swap(i, smallest);
            i = smallest;
            animationState.focusIndices = [i]; // Focus on the node that moved down
            drawHeap([i]);
            await new Promise(resolve => setTimeout(resolve, 150));
        }
    }

    async function insertElement(value) {
        if (heap.length >= MAX_NODES) return false;
        
        const currentIndex = heap.length;
        heap.push(value);

        animationState.focusIndex = currentIndex;
        drawHeap([currentIndex]);
        await new Promise(resolve => setTimeout(resolve, 100));

        await bubbleUp(currentIndex);
        return true;
    }

    async function extractMin() {
        if (heap.length === 0) return false;

        const minVal = heap[0];
        let lastIndex = heap.length - 1;

        // Handle single element case
        if (heap.length === 1) {
            animationState.focusIndices = [];
            drawHeap();
            await new Promise(resolve => setTimeout(resolve, 500));
            return null;
        }

        // Move last element to root and pop it logically
        heap[0] = heap[lastIndex];
        heap.pop();

        animationState.focusIndices = [0, lastIndex]; // Show the swap preparation visually (though we only move one)
        drawHeap(animationState.focusIndices);
        await new Promise(resolve => setTimeout(resolve, 200));
        
        // Start sink-down from the root
        await sinkDown(0);

        return minVal;
    }


    // --- Main Animation Loop ---

    let insertCount = 0;
    let extractCount = 0;

    async function animate() {
        if (isAnimating) return;
        isAnimating = true;

        try {
            drawHeap(); // Initial draw
            await new Promise(resolve => setTimeout(resolve, 500)); 

            // 1. Perform a few insertions first to build the heap
            for(let i=0; i<Math.min(8, MAX_NODES - heap.length); i++) {
                const randomVal = Math.floor(Math.random() * 50) + i;
                await insertElement(randomVal);
                insertCount++;
            }

            // 2. Alternating phases
            while (heap.length > 0 && insertCount < 15 && extractCount < 15) {
                if ((insertCount + extractCount) % 4 == 0 || heap.length < 3) {
                    // Insert Phase
                    const randomVal = Math.floor(Math.random() * 50);
                    await insertElement(randomVal);
                    insertCount++;
                } else {
                    // Extract-Min Phase
                    const minVal = await extractMin();
                    if (minVal !== null) {
                        console.log(`Extracted Min: ${minVal}`);
                    }
                    extractCount++;
                }
            }

        } catch(e) {
            console.error("Animation error:", e);
        } finally {
            isAnimating = false;
            document.getElementById('status').innerHTML = `Operations: Inserts=${insertCount}<br>Extracts=${extractCount}`;
            setTimeout(() => animate(), 100); // Loop back to restart if finished/empty
        }
    }

    // Inject status display (must be done manually or included in the HTML structure)
    const style = document.createElement('style');
    style.textContent = `#status { position: absolute; top: 10px; left: 10px; font-family: sans-serif; color: #333; }`;
    document.head.appendChild(style);

    const statusDiv = document.createElement('div');
    statusDiv.id = 'status';
    statusDiv.innerHTML = `Operations: Inserts=0<br>Extracts=0`;
    document.body.appendChild(statusDiv);


    animate();
</script></body></html>
```
mistral-small:24bERRBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Binary Min-Heap 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 #000; }
#info { position: absolute; top: 20px; left: 20px; font-family: Arial, sans-serif; color: #333; }
</style>
</head>
<body>
<div id="info"></div><canvas id="heapCanvas" width="800" height="600"></canvas>
<script>
const canvas = document.getElementById('heapCanvas');
const ctx = canvas.getContext('2d');
const infoDiv = document.getElementById('info');
let insertCount = 0;
let extractCount = 0;
let heap = [];
let radius = 30;

function drawCircle(x, y, value, highlight) {
  ctx.beginPath();
  ctx.arc(x, y, radius, 0, Math.PI * 2);
  ctx.fillStyle = highlight ? 'yellow' : 'white';
  ctx.strokeStyle = '#000';
  ctx.lineWidth = 2;
  ctx.fill();
  ctx.stroke();
  ctx.font = '16px Arial';
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.fillStyle = '#000';
  ctx.fillText(value, x, y);
}

function drawEdge(x1, y1, x2, y2) {
  ctx.beginPath();
  ctx.moveTo(x1, y1);
  ctx.lineTo(x2, y2);
  ctx.strokeStyle = '#000';
  ctx.lineWidth = 2;
  ctx.stroke();
}

function getCoordinates(index, levelCount) {
  const xOffset = canvas.width / (levelCount + 1);
  const yOffset = radius * 3;
  const level = Math.floor(Math.log2(index + 1));
  const row = level * yOffset;
  const col = index - Math.pow(2, level) + 1;
  return { x: col * xOffset, y: row };
}

function drawHeap() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  for (let i = 0; i < heap.length; i++) {
    const coords = getCoordinates(i, Math.ceil(Math.log2(heap.length + 1)));
    drawCircle(coords.x, coords.y, heap[i], false);
    if (i > 0) {
      const parentCoords = getCoordinates(Math.floor((i - 1) / 2), Math.ceil(Math.log2(heap.length + 1)));
      drawEdge(parentCoords.x, parentCoords.y, coords.x, coords.y);
    }
  }
}

function heapifyUp(index) {
  let currentIndex = index;
  while (currentIndex > 0 && heap[currentIndex] < heap[Math.floor((currentIndex - 1) / 2)]) {
    const parentIndex = Math.floor((currentIndex - 1) / 2);
    [heap[currentIndex], heap[parentIndex]] = [heap[parentIndex], heap[currentIndex]];
    drawHeap();
    let swapCoords = getCoordinates(currentIndex, Math.ceil(Math.log2(heap.length + 1)));
    let parentSwapCoords = getCoordinates(parentIndex, Math.ceil(Math.log2(heap.length + 1)));
    ctx.clearRect(swapCoords.x - radius, swapCoords.y - radius, radius * 2, radius * 2);
    ctx.clearRect(parentSwapCoords.x - radius, parentSwapCoords.y - radius, radius * 2, radius * 2);
    drawCircle(swapCoords.x, swapCoords.y, heap[currentIndex], true);
    drawCircle(parentSwapCoords.x, parentSwapCoords.y, heap[parentIndex], false);
    yield;
    ctx.clearRect(swapCoords.x - radius, swapCoords.y - radius, radius * 2, radius * 2);
    ctx.clearRect(parentSwapCoords.x - radius, parentSwapCoords.y - radius, radius * 2, radius * 2);
    drawCircle(swapCoords.x, swapCoords.y, heap[currentIndex], false);
    drawCircle(parentSwapCoords.x, parentSwapCoords.y, heap[parentIndex], false);
    currentIndex = parentIndex;
  }
}

function heapifyDown(index) {
  let currentIndex = index;
  while (2 * currentIndex + 1 < heap.length) {
    const leftChildIndex = 2 * currentIndex + 1;
    const rightChildIndex = 2 * currentIndex + 2;
    let smallestIndex = currentIndex;

    if (heap[leftChildIndex] < heap[smallestIndex]) {
      smallestIndex = leftChildIndex;
    }

    if (rightChildIndex < heap.length && heap[rightChildIndex] < heap[smallestIndex]) {
      smallestIndex = rightChildIndex;
    }

    if (currentIndex === smallestIndex) break;

    [heap[currentIndex], heap[smallestIndex]] = [heap[smallestIndex], heap[currentIndex]];
    drawHeap();
    let swapCoords = getCoordinates(currentIndex, Math.ceil(Math.log2(heap.length + 1)));
    let childSwapCoords = getCoordinates(smallestIndex, Math.ceil(Math.log2(heap.length + 1)));
    ctx.clearRect(swapCoords.x - radius, swapCoords.y - radius, radius * 2, radius * 2);
    ctx.clearRect(childSwapCoords.x - radius, childSwapCoords.y - radius, radius * 2, radius * 2);
    drawCircle(swapCoords.x, swapCoords.y, heap[currentIndex], true);
    drawCircle(childSwapCoords.x, childSwapCoords.y, heap[smallestIndex], false);
    yield;
    ctx.clearRect(swapCoords.x - radius, swapCoords.y - radius, radius * 2, radius * 2);
    ctx.clearRect(childSwapCoords.x - radius, childSwapCoords.y - radius, radius * 2, radius * 2);
    drawCircle(swapCoords.x, swapCoords.y, heap[currentIndex], false);
    drawCircle(childSwapCoords.x, childSwapCoords.y, heap[smallestIndex], false);
    currentIndex = smallestIndex;
  }
}

async function insertRandomValue() {
  const value = Math.floor(Math.random() * 100);
  heap.push(value);
  await heapifyUp(heap.length - 1)[Symbol.asyncIterator]().next();
  drawHeap();
  infoDiv.innerText = `Inserts: ${++insertCount}, Extracts: ${extractCount}`;
}

async function extractMin() {
  if (heap.length === 0) return;
  const minValue = heap[0];
  heap[0] = heap.pop();
  await heapifyDown(0)[Symbol.asyncIterator]().next();
  drawHeap();
  infoDiv.innerText = `Inserts: ${insertCount}, Extracts: ${++extractCount}`;
}

async function runAnimation() {
  while (true) {
    for (let i = 0; i < 5 && heap.length < 20; i++) {
      await insertRandomValue();
    }
    if (heap.length > 1) {
      await extractMin();
    } else {
      return;
    }
  }
}

runAnimation().then(() => setTimeout(runAnimation, 3000));
</script>
</body>
</html>
```
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.
qwen3-coder:30bERRBLANKLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Min Heap Visualization</title>
    <style>
        body { background: #111; color: white; font-family: monospace; display: flex; flex-direction: column; align-items: center; margin: 0; }
        canvas { border: 1px solid #333; background: #222; }
        #status { padding: 10px; text-align: center; font-size: 1.2em; color: #ccc;}
    </style>
</head>
<body>
    <div id="status">Ready. Heap Size: 0 | Inserts: 0 | Extracts: 0</div>
    <canvas id="heapCanvas" width="800" height="600"></canvas>

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

        // --- Configuration and State ---
        let heapArray = [];
        let history = []; // Stores animation steps
        let currentStep = 0;
        let isAnimating = false;

        const NODE_RADIUS = 25;
        const ANIMATION_DELAY = 100; // Milliseconds per swap step

        // Animation State Management
        class AnimationState {
            constructor(type, steps) {
                this.type = type; // 'INSERT' or 'EXTRACT'
                this.steps = steps;
                this.stepIndex = 0;
                this.lastTime = performance.now();
            }

            update(time) {
                if (!this.isFinished && time - this.lastTime > ANIMATION_DELAY * (this.stepIndex + 1)) {
                    this.stepIndex++;
                    this.lastTime = time;
                    return true; // Needs drawing update
                }
                return false;
            }

            isFinished() {
                return this.stepIndex >= this.steps.length - 1;
            }
        }

        // --- Utility Functions ---

        function getNextHeapPosition(index) {
            let level = Math.floor(Math.log2(heapArray.length)) - 1;
            if (level < 0) return { x: canvas.width / 2, y: canvas.height / 2 }; // Should not happen for empty heap

            // Calculate starting coordinates based on a perfect binary tree layout
            const width = canvas.width;
            const height = canvas.height;
            const rowHeight = 80;
            const nodeSpacing = (width - (NODE_RADIUS * 2)) / Math.pow(2, level + 1);

            let x = nodeSpacing * (Math.pow(2, level) - 1) + (index % (Math.pow(2, level + 1))) * nodeSpacing;
            let y = rowHeight * (level + 1);
            return { x: x || width / 2, y: y }; // Fallback for centering
        }

        function getCoords(i) {
             // Simplified coordinate calculation that works well for moderate heap sizes
             const depth = Math.floor(Math.log2(i + 1));
             const levelHeight = 80;
             let y = levelHeight * (depth + 1);

             if (depth === 0) return { x: canvas.width / 2, y: y }; // Root

             // Calculate horizontal position based on index i
             const maxNodesAtLevel = Math.pow(2, depth + 1) - 1;
             let x_offset = (canvas.width - NODE_RADIUS * 2) / (Math.pow(2, depth));
             let x = x_offset * (i & -(i & -i) == i ? Math.log2(i+1) : Math.floor(i/Math.pow(2, depth)) + 1);

            // More robust coordinate calculation based on standard binary tree layout:
            const totalWidth = canvas.width;
            let x_pos = (totalWidth / Math.pow(2, Math.floor(Math.log2(heapArray.length))) ) * (i % Math.pow(2, Math.floor(Math.log2(heapArray.length))));
            let y_pos = 80 * Math.floor(Math.log2(i + 1));

             return { x: totalWidth / 2 + ((i - 1) % (Math.pow(2, Math.floor(Math.log2(heapArray.length))))) * (totalWidth / Math.pow(2, Math.floor(Math.log2(heapArray.length))) + 5), y: 80 * (Math.floor(Math.log2(i+1)) - 1) };
        }


        // --- Drawing Logic ---

        function drawNode(index, coords, value, highlight = false) {
            ctx.beginPath();
            ctx.arc(coords.x, coords.y, NODE_RADIUS, 0, Math.PI * 2);
            
            if (highlight) {
                ctx.fillStyle = '#ffbb00'; // Highlight color
                ctx.strokeStyle = '#f89a00';
            } else {
                ctx.fillStyle = '#4466aa';
                ctx.strokeStyle = '#334477';
            }
            ctx.lineWidth = 2;
            ctx.fill();
            ctx.stroke();

            // Draw text (value)
            ctx.fillStyle = 'white';
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            ctx.fillText(value, coords.x, coords.y);
        }

        function drawEdge(parentCoords, childCoords) {
            ctx.beginPath();
            ctx.moveTo(parentCoords.x, parentCoords.y);
            ctx.lineTo(childCoords.x, childCoords.y);
            ctx.strokeStyle = '#888';
            ctx.lineWidth = 1.5;
            ctx.stroke();
        }

        function renderCanvas() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            if (heapArray.length === 0) return;

            // Map indices to coordinates for drawing
            const coordsMap = {};
            for (let i = 0; i < heapArray.length; i++) {
                // Use a standardized, slightly offset coordinate system for better visibility
                const depth = Math.floor(Math.log2(i + 1));
                let y_pos = 50 + depth * 90;
                let x_range = canvas.width - 80;
                let numNodesAtLevel = Math.pow(2, depth);

                let x_pos = (Math.pow(2, depth) / Math.pow(2, Math.floor(Math.log2(heapArray.length)))) * i + ((i % (1 << depth)) - 1) * (x_range / numNodesAtLevel) + (x_range / numNodesAtLevel);

                // Simple fixed layout for visualization clarity
                let x = canvas.width / 2 + Math.pow(2, Math.floor(Math.log2(heapArray.length))) * (i - Math.pow(2, Math.floor(Math.log2(heapArray.length)))) * 5;
                if (isNaN(x)) x = canvas.width / 2 + ((i - 1) % (1 << Math.floor(Math.log2(heapArray.length)))) * (canvas.width / (1 << Math.floor(Math.log2(heapArray.length))) + 5);
                let y = 50 + Math.floor(Math.log2(i+1)) * 90;

                 coordsMap[i] = { x: x, y: y }; // Use the calculated coords

            }


            // 1. Draw Edges (Parent to Child)
            for (let i = 1; i < heapArray.length; i++) {
                const parentIndex = Math.floor((i - 1) / 2);
                if (coordsMap[parentIndex] && coordsMap[i]) {
                    drawEdge(coordsMap[parentIndex], coordsMap[i]);
                }
            }

            // 2. Draw Nodes
            for (let i = 0; i < heapArray.length; i++) {
                const value = heapArray[i];
                const coords = coordsMap[i] || getNextHeapPosition(i); // Fallback if map failed
                drawNode(i, coords, value);
            }
        }

        // --- Heap Operations (BubbleUp / SinkDown) ---

        /** Bubbles up the element at 'childIndex' until heap property is restored or it reaches root. */
        function bubbleUpAnimation(startIndex) {
            let parentIndex = Math.floor((startIndex - 1) / 2);
            if (parentIndex < 0) return []; // Already at root

            const steps = [];
            let currentChild = startIndex;

            while (currentChild > 0 && heapArray[currentChild] < heapArray[parentIndex]) {
                steps.push({
                    type: 'SWAP',
                    indices: [currentChild, parentIndex],
                    highlightIndices: [currentChild, parentIndex]
                });

                // Perform the actual swap in the underlying array for subsequent steps to reference correct data
                [heapArray[currentChild], heapArray[parentIndex]] = [heapArray[parentIndex], heapArray[currentChild]];

                currentChild = parentIndex;
                parentIndex = Math.floor((currentChild - 1) / 2);
            }
            return steps;
        }

        /** Sinks down the element at 'startIndex' until heap property is restored. */
        function sinkDownAnimation(startIndex) {
            const steps = [];
            let currentIndex = startIndex;

            while (true) {
                let leftChild = 2 * currentIndex + 1;
                let rightChild = 2 * currentIndex + 2;
                let smallest = currentIndex;

                // Find the smallest among current, left, and right children
                if (leftChild < heapArray.length && heapArray[leftChild] < heapArray[smallest]) {
                    smallest = leftChild;
                }
                if (rightChild < heapArray.length && heapArray[rightChild] < heapArray[smallest]) {
                    smallest = rightChild;
                }

                // If smallest is the current index, we are done
                if (smallest === currentIndex) break;

                steps.push({
                    type: 'SWAP',
                    indices: [currentIndex, smallest],
                    highlightIndices: [currentIndex, smallest]
                });

                // Perform swap
                [heapArray[currentIndex], heapArray[smallest]] = [heapArray[smallest], heapArray[currentIndex]];

                currentIndex = smallest;
            }
            return steps;
        }


        // --- Main Control Flow ---

        function appendSteps(steps) {
            history.push(...steps);
            updateStatus();
        }

        function updateStatus() {
             const size = heapArray.length;
             let insertsCount = history.filter(s => s.type === 'INSERT').length;
             let extractCount = history.filter(s => s.type === 'EXTRACT').length;
            
             statusElement.innerHTML = `Heap Size: ${size} | Inserts: ${insertsCount} | Extracts: ${extractCount}`;
        }

        async function insertMin(value) {
            const steps = [];
            // 1. Add element to the end
            heapArray.push(value);
            
            // Note: The first step is just adding it (no swap needed)
            steps.push({ type: 'INITIAL_INSERT', indices: [heapArray.length - 1], highlightIndices: [heapArray.length - 1] });

            // 2. Bubble Up Animation
            const bubbleUpSteps = bubbleUpAnimation(heapArray.length - 1);
            steps.push(...bubbleUpSteps);
            return steps;
        }

        function extractMinHeap() {
            if (heapArray.length === 0) return [];

            // 1. Store root value
            const rootValue = heapArray[0];
            
            // 2. Handle case where only one element remains
            if (heapArray.length === 1) {
                history.push({ type: 'EXTRACT', indices: [0], highlightIndices: [0] ]);
                return [{ type: 'FINAL_POP' }];
            }

            // 3. Move last element to root
            const lastValue = heapArray[heapArray.length - 1];
            heapArray[0] = lastValue;
            heapArray.pop(); // Remove the old last value
            
            // The new root (last element) needs sinking down
            const sinkDownSteps = sinkDownAnimation(0);
            
            return [{ type: 'EXTRACT', indices: [0], highlightIndices: [0] }, ...sinkDownSteps, { type: 'FINAL_POP' }];
        }

        // --- Animation Loop ---

        function animateStep() {
            if (!isAnimating) return;

            const state = history[history.length - 1];
            if (!state || !state.update(performance.now())) {
                // Still waiting for the step delay to pass
                requestAnimationFrame(animateStep);
                return;
            }

            let highlights = [];
            let message = "";

            if (state.type === 'SWAP') {
                const [i, j] = state.indices;
                highlights = state.highlightIndices;
                message = `Swapping ${heapArray[i]} and ${heapArray[j]}.`;
            } else if (state.type === 'INITIAL_INSERT') {
                 const i = state.indices[0];
                 highlights = [i];
                 message = `Inserted ${heapArray[i]}. Bubbling up...`;
            } else if (state.type === 'EXTRACT') {
                // This step signifies the removal of the root before sinking down starts
                message = `Min value (${history[0].highlightIndices[0] === 0 ? heapArray[0] : 'N/A']}) extracted. Replacing root with last element...`;
            } else if (state.type === 'FINAL_POP') {
                 // This step signals the completion of the operation and the removal from the array
                message = `Operation complete! Value ${history[0].highlightIndices[0] === 0 ? heapArray[0] : 'N/A'} was the min value extracted.`;
            }

            renderCanvas(); // Redraw current state
            statusElement.innerHTML += `<br><strong>Status:</strong> ${message}`;


            if (state.isFinished()) {
                // Operation complete, reset animation state and prepare next operation
                history = [];
                isAnimating = false;
                updateStatus(); 
                setTimeout(() => {
                    runNextPhase();
                }, 1500); // Wait a moment before starting the next phase
            } else {
                requestAnimationFrame(animateStep);
            }
        }

        // --- Machine State Logic ---

        let operationCounter = 0;
        const MAX_OPERATIONS = 8;

        function runNextPhase() {
            if (operationCounter >= MAX_OPERATIONS && heapArray.length === 0) {
                alert("Simulation finished. Restarting!");
                resetSystem();
                return;
            }

            // Determine phase: Alternate Insert and ExtractMin
            const isInsertPhase = operationCounter % 2 === 0 || (heapArray.length === 0 && operationCounter === 0);
            operationCounter++;

            if (isInsertPhase) {
                let randomValue = Math.floor(Math.random() * 100) + 1;
                const steps = insertMin(randomValue);
                history = steps;
                isAnimating = true;
                animateStep();
            } else {
                if (heapArray.length === 0) {
                    // If we need to extract but the heap is empty, force an insertion first.
                    console.warn("Forcing insert before extract.");
                    const randomValue = Math.floor(Math.random() * 100) + 1;
                    history = insertMin(randomValue);
                    isAnimating = true;
                    animateStep();
                    return;
                }

                // Extract Min
                const steps = extractMinHeap();
                history = steps;
                isAnimating = true;
                animateStep();
            }
        }

        function resetSystem() {
            heapArray = [];
            history = [];
            currentStep = 0;
            operationCounter = 0;
            isAnimating = false;
            statusElement.innerHTML = "Ready. Heap Size: 0 | Inserts: 0 | Extracts: 0";
            renderCanvas();
        }

        // Initialize the simulation
        window.onload = () => {
             resetSystem();
             setTimeout(runNextPhase, 500); // Start after a half-second delay
        };
    </script>
</body>
</html>
```
qwen3:14bOKLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"><title>Min-Heap Animation</title>
    <style>body{margin:0;background:#111;overflow:hidden}canvas{display:block}</style>
</head>
<body><canvas id="heapCanvas"></canvas><script>
const canvas = document.getElementById('heapCanvas');
const ctx = canvas.getContext('2d');
let W, H;

// Heap state variables
let heapArr = []; 
let operationCount = { inserts: 0, extracts: 0 };
let isAnimating = false;
let animationFrameId = null;

// Animation State tracking
let currentOperation = ''; // 'insert' or 'extract'
let pathHistory = [];      // Stores [index1, index2] for swaps
let swapIndexA = -1;       // Source index A of the current swap
let swapIndexB = -1;       // Target index B of the current swap
let stepDelay = 0;         // Time delay counter
const DELAY_FRAMES = 15;   // Duration of pause/highlight

function resizeCanvas() {
    W = window.innerWidth;
    H = window.innerHeight;
    canvas.width = W;
    canvas.height = H * 0.9;
}

window.addEventListener('resize', resizeCanvas);
resizeCanvas();

// --- Drawing Functions ---

function getCoords(i) {
    if (i < 0 || i >= heapArr.length) return null;
    let k = i + 1; // 1-based index for easier math
    let level = Math.floor(Math.log2(k)) - 1;
    let nodes_at_level = Math.min(heapArr.length, (1 << (level + 1)) - 1);
    let start_x = W * (Math.pow(2, level) - 1) / (Math.pow(2, level));
    let x = W * (Math.pow(2, level - i % Math.pow(2, level))) / (2 * Math.pow(2, level));
    let y = H * (level + 1) / 8;

    // Simplified coordinate calculation for better visual spread
    let max_width = Math.pow(2, Math.floor(Math.log2(heapArr.length)) + 1);
    let xPos = W * ((i % max_width) - (max_width / 2 - 0.5)) / max_width;
    let yPos = H * (Math.floor(Math.log2(i + 1)) * 0.7 + 0.3);

    // Final robust approximation: Use a fixed scale based on depth/span
    const maxDepth = Math.max(1, Math.floor(Math.log2(heapArr.length) + 1));
    let levelFactor = (i < 8) ? 0.9 : 1; // Adjust spacing for initial nodes
    let x_coord = W * (Math.sin((i / heapArr.length) * Math.PI * 2) + 1) / 2 * 0.6;
    let y_coord = H * (Math.floor(Math.log2(i + 1)) * 0.7);

    // A simpler, more reliable layout that guarantees spacing:
    const depth = Math.floor(Math.log2(i + 1));
    if (depth > 6) return {x: W/2, y: H*0.95}; // Fallback for large heaps

    let level_nodes = Math.pow(2, depth);
    let x_pos_calc = W * (i % level_nodes) / level_nodes;
    let y_pos_calc = H * (depth + 1) / 10;

    // Adjusting for the actual breadth of the heap
    let num_leaves = Math.pow(2, depth);
    if (num_leaves > 1 && i >= Math.pow(2, depth - 1)) {
        x_coord = W * (i % num_leaves) / num_leaves;
        y_coord = H * ((depth + 1) * 0.7);
    } else if (depth === 0) {
         x_coord = W/2; y_coord = H*0.3;
    } else {
        // Fallback for general structure
        let nodes_on_level = Math.pow(2, depth + 1);
        x_coord = (i % nodes_on_level) / nodes_on_level * W * 0.8 + W * 0.1;
        y_coord = H * ((depth + 1) / 9);
    }

    return { x: Math.max(50, Math.min(W - 50, x_coord)), y: Math.max(50, Math.min(H - 50, y_coord)) };
}


function drawHeap() {
    ctx.clearRect(0, 0, W, H);

    // Draw edges first
    for (let i = 0; i < heapArr.length; i++) {
        const node = i + 1; // Use 1-based index for parent/child logic
        if (node === 1) continue; // Root has no parent edge

        const p = Math.floor(node / 2);
        
        // Only draw edges if the nodes are currently visible and not being swapped
        if (p >= heapArr.length || node > heapArr.length) continue;

        const cCoords = getCoords(i);
        const pCoords = getCoords(p - 1); // i is 0-based, but drawHeap uses indices directly

        // Reverting to simple index based positioning for robust drawing
        if (cCoords && pCoords) {
             ctx.beginPath();
             ctx.moveTo(pCoords.x, pCoords.y);
             ctx.lineTo(cCoords.x, cCoords.y);
             ctx.strokeStyle = '#555';
             ctx.lineWidth = 2;
             ctx.stroke();
        }
    }

    // Draw nodes and values
    for (let i = 0; i < heapArr.length; i++) {
        const val = heapArr[i];
        const coords = getCoords(i);
        if (!coords) continue;

        ctx.beginPath();
        ctx.arc(coords.x, coords.y, 30, 0, Math.PI * 2);

        let color = '#4a90e2'; // Default blue
        let highlight = false;

        // Highlight currently swapping nodes
        if (i === swapIndexA || i === swapIndexB) {
            color = '#ffeb3b'; // Yellow for active swap
            highlight = true;
        } else if (pathHistory.includes(i)) {
            // Simple visual indicator that this node was part of the recent path
             color = '#8bc34d'; 
        }

        ctx.fillStyle = color;
        ctx.strokeStyle = '#2c3e50';
        ctx.lineWidth = 2;
        ctx.fill();
        ctx.stroke();

        // Draw value text
        ctx.fillStyle = '#fff';
        ctx.font = 'bold 18px Arial';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText(val, coords.x, coords.y);
    }

    // Draw stats panel
    ctx.fillStyle = '#fff';
    ctx.fillRect(20, 20, 300, 50);
    ctx.font = '18px Arial';
    ctx.textAlign = 'left';
    ctx.fillStyle = '#333';
    ctx.fillText(`Inserts: ${operationCount.inserts}`, 30, 40);
    ctx.fillText(`Extracts: ${operationCount.extracts}`, 150, 40);
}

// --- Heap Logic Functions ---

function swap(i, j) {
    [heapArr[i], heapArr[j]] = [heapArr[j], heapArr[i]];
}

async function bubbleUp(index) {
    let i = index;
    while (i > 0) {
        const p = Math.floor((i - 1) / 2); // Parent index
        if (heapArr[i] < heapArr[p]) {
            pathHistory.push(i); pathHistory.push(p);
            swap(i, p);
            pathHistory.shift(); // Remove old state marks if needed
            i = p;
            // Wait for animation frame pause
            await new Promise(resolve => setTimeout(resolve, 100));
        } else {
            break;
        }
    }
}

async function sinkDown(index) {
    let i = index;
    const N = heapArr.length;
    while (true) {
        let left = 2 * i + 1;
        let right = 2 * i + 2;
        let smallest = i;

        if (left < N && heapArr[left] < heapArr[smallest]) {
            smallest = left;
        }
        if (right < N && heapArr[right] < heapArr[smallest]) {
            smallest = right;
        }

        if (smallest !== i) {
            pathHistory.push(i); pathHistory.push(smallest);
            swap(i, smallest);
            i = smallest;
            // Wait for animation frame pause
            await new Promise(resolve => setTimeout(resolve, 100));
        } else {
            break;
        }
    }
}

async function handleInsert() {
    if (heapArr.length > 50) return; // Prevent memory overflow/lag

    const newValue = Math.floor(Math.random() * 99) + 1;
    const newIndex = heapArr.length;
    heapArr.push(newValue);
    operationCount.inserts++;

    await bubbleUp(newIndex);
}

async function handleExtractMin() {
    if (heapArr.length < 2) return;

    // The root is the min element
    const minValue = heapArr[0];
    
    // Swap root with last element
    swap(0, heapArr.length - 1);

    await new Promise(resolve => setTimeout(resolve, 200)); // Pause to show extraction

    // Remove the old root (now at the end) and set the new size
    heapArr.pop();
    operationCount.extracts++;
    
    if (heapArr.length > 0) {
        const lastElementIndex = 0; // The element moved to the root
        await sinkDown(lastElementIndex);
    }
}

// --- Animation Loop and State Machine ---

async function runAnimationStep() {
    isAnimating = true;
    drawHeap();

    try {
        if (currentOperation === 'insert') {
            await handleInsert();
        } else if (currentOperation === 'extract') {
            await handleExtractMin();
        }
    } catch(e) {
        console.error("Animation error:", e);
        isAnimating = false;
    }

    // Reset path history and redraw after the operation is complete
    pathHistory = []; 
    drawHeap();
    
    // Determine next phase
    if (heapArr.length === 0) {
        console.log("Heap emptied, restarting.");
        heapArr = [10]; // Start fresh for continuation
        operationCount = { inserts: 0, extracts: 0 };
        currentOperation = 'insert';
    } else if ((operationCount.inserts > 3 && operationCount.extracts >= 2) || (Math.random() < 0.1)) {
         // Attempt to switch phases or stop if heap is small/stale
        if (Math.random() > 0.5) {
            currentOperation = 'insert';
        } else {
            currentOperation = 'extract';
        }
    } else if (currentOperation === '') {
         // Initial start condition
         currentOperation = 'insert';
    }

    if (isAnimating) {
        animationFrameId = requestAnimationFrame(runAnimationStep);
    }
}

function startLoop() {
    if (animationFrameId) cancelAnimationFrame(animationFrameId);
    isAnimating = true;
    requestAnimationFrame(runAnimationStep);
}

startLoop();

</script></body></html>
```
deepseek-r1:14bERRBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html><body style="margin:0;overflow:hidden;">
<canvas id="c"></canvas>
<div id="s" style="position:absolute;top:10;left:10;"></div>
<script>
const c=document.getElementById('c'),s=document.getElementById('s');
const w=c.width=800,h=c.height=600;
let heap=[],heapSize=0,nOperations=0;

class Node{
  constructor(v,p){
    this.v=v;this.p=p;this.c=[];this.s=15;
    this.x=0,this.y=0;
    this highlighted=false;
    this.parent=null;
    this.children=[];
  }
}

class BinaryMinHeap{
  constructor(){this.nodes=[]}
  
  insert(v){
    let node=new Node(v,null);
    if(heap.length===0){heap.push(node);node.x=w/2;node.y=50;node.parent=null;}
    else{let i=heap.length;p=i>1?(i-1)/2 :0;
      while(i>p && (heap[p].v > v || (heap[p].v==v && p<i))){i=p;p=(p-1)/2 |0}
      node=new Node(v,heap[p]);node.parent=heap[p];node.x=node.p.x + (Math.random()*30>15 ? 40 : -40);node.y=node.p.y+60;
      while(node.parent && (node.v < node.parent.v || (node.v==node.parent.v && heap.indexOf(node) < heap.indexOf(node.parent)))){let t=node.parent;t.p=node;heap.splice(heap.indexOf(t),1, node,...t);node=t;}else if(p!=i){heap[i]=node;if(i>p){let j=p,i=i;
      while(j<i){[heap[j],heap[i]]=[heap[i],heap[j]];j=(j+1)/2 |0;i=j}}
    }heap.push(node);node=new Node(v,node.parent)}
  }
  
  extractMin(){if(heap.length===0)return null;
    let min=heap[0];let last=heap.pop();nOperations++;s.textContent=`Insert: ${insertCount} Extract: ${extractCount}`;
    if(!last)return;let i=0,l=heap.length;
    while(i<l && (last.v < heap[i].v || (last.v==heap[i].v && i < l))){i=(i*2 +1)<l ?(i*2 +1) : l-1}
    if(i>=l){heap.push(last);return min;}
    let t=heap[i];heap.splice(i,1);heap.unshift(last);
    while(i<heap.length && (last.v < heap[i].v || (last.v==heap[i].v && i < this.heap.length))){i=(i*2 +1)<this.heap.length ?(i*2 +1) :this.heap.length-1}
    if(!t.p)t.parent=null;
    last.p=t;if(t)c.lastChild?.remove();else c.beginPath(),c.arc(w/2,50,last.s,0,Math.PI*2),c.fillText(last.v.toString(),w/2,45);
  }
}

let heap=new BinaryMinHeap();

function draw(){c.clearRect(0,0,w,h);heap.nodes.forEach(n=>{c.beginPath();c.arc(n.x,n.y,n.s,0,Math.PI*2);c.fillText(n.v,n.x,n.y-3)})}

setInterval(()=>{
    if(Math.random()<.1 && heapSize<50)heap.insert(Math.floor(Math.random()*100));
    draw();
},100);

</script>
</body></html>
```
llama3.1:8bERRSTATFORMAT
Show code
```html
<!DOCTYPE html>
<html>
<head>
<style>
body {
  margin: 0;
  background-color: #f0f0f0;
}

canvas {
  border: 1px solid black;
}
</style>
</head>
<body>
<script>
let heap = [];
let insertCount = 0;
let extractMinCount = 0;

function random(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function drawHeap(heap, canvas) {
  let ctx = canvas.getContext('2d');
  let radius = 20;
  let paddingX = 10;
  let paddingY = 10;
  let levelWidth = 0;
  let nodeLevel = [];
  for (let i = heap.length - 1; i >= 0; --i) {
    if (!nodeLevel[i]) {
      levelWidth += radius * 2 + paddingX;
      nodeLevel.push([]);
    }
    nodeLevel[i].push(heap[i]);
  }

  ctx.clearRect(0, 0, canvas.width, canvas.height);
  for (let i = 0; i < nodeLevel.length; ++i) {
    let x = levelWidth / 2 + paddingX;
    let y = i * radius * 3 + paddingY;
    let angle = Math.PI / 4;
    for (let j = 0; j < nodeLevel[i].length; ++j) {
      ctx.beginPath();
      ctx.arc(x, y, radius, -angle, angle);
      ctx.fillStyle = 'white';
      ctx.fill();
      ctx.font = '12px Arial';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillStyle = 'black';
      ctx.fillText(nodeLevel[i][j], x, y);
      let prevX = x;
      for (let k = 0; k < nodeLevel[i].length - 1; ++k) {
        if ((nodeLevel[i][k] < nodeLevel[i][k + 1])) {
          ctx.beginPath();
          ctx.moveTo(prevX, y + radius * Math.cos(angle));
          ctx.lineTo(x, y);
          ctx.stroke();
          prevX = x;
        }
      }
      let nextX = x;
      for (let k = j - 1; k >= 0; --k) {
        if ((nodeLevel[i][j] < nodeLevel[i][k])) {
          ctx.beginPath();
          ctx.moveTo(x, y + radius * Math.cos(angle));
          ctx.lineTo(nextX, y);
          ctx.stroke();
          nextX = x;
        }
      }
      x += radius * 2 + paddingX;
    }
  }

  ctx.font = '12px Arial';
  ctx.textAlign = 'left';
  ctx.textBaseline = 'top';
  ctx.fillStyle = 'black';
  ctx.fillText(`Heap Size: ${heap.length}`, paddingX, paddingY);
  ctx.fillText(`Inserts: ${insertCount}`, paddingX, paddingY + 20);
  ctx.fillText(`Extract-Min: ${extractMinCount}`, paddingX, paddingY + 40);

  let canvasWidth = levelWidth + 2 * paddingX;
  if (canvas.width < canvasWidth) {
    canvas.width = canvasWidth;
  }
}

function insertValue() {
  let value = random(1, 100);
  heap.push(value);
  let nodeIndex = heap.length - 1;
  while ((nodeIndex > 0) && (heap[nodeIndex] < heap[Math.floor((nodeIndex - 1) / 2)])) {
    [heap[nodeIndex], heap[Math.floor((nodeIndex - 1) / 2)]] = [heap[Math.floor((nodeIndex - 1) / 2)], heap[nodeIndex]];
    let highlightColor = 'red';
    drawHeap(heap, document.getElementById('canvas'));
    requestAnimationFrame(() => {
      let ctx = document.getElementById('canvas').getContext('2d');
      ctx.font = '12px Arial';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillStyle = highlightColor;
      ctx.fillText(value, 100 + (nodeIndex % 4) * 150, 200);
    });
    requestAnimationFrame(() => {
      let ctx = document.getElementById('canvas').getContext('2d');
      ctx.font = '12px Arial';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillStyle = 'black';
      ctx.fillText(value, 100 + (nodeIndex % 4) * 150, 200);
    });
    requestAnimationFrame(() => {
      let nodeIndex2 = Math.floor((nodeIndex - 1) / 2);
      [heap[nodeIndex2], heap[nodeIndex]] = [heap[nodeIndex], heap[nodeIndex2]];
      drawHeap(heap, document.getElementById('canvas'));
    });
    await new Promise(resolve => globalThis.setTimeout(() => resolve(), 1000));
    nodeIndex = Math.floor((nodeIndex - 1) / 2);
  }
  insertCount++;
}

function extractMinValue() {
  let min = heap[0];
  heap[0] = heap.pop();
  if (heap.length > 0) {
    let lastIndex = heap.length - 1;
    heap[lastIndex] = min;
    let nodeIndex = 0;
    while ((2 * nodeIndex + 1 < heap.length)) {
      let smallestChildIndex = 2 * nodeIndex + 1;
      if ((2 * nodeIndex + 2 < heap.length) && (heap[smallestChildIndex] > heap[2 * nodeIndex + 2])) {
        smallestChildIndex = 2 * nodeIndex + 2;
      }
      if (heap[nodeIndex] > heap[smallestChildIndex]) {
        [heap[nodeIndex], heap[smallestChildIndex]] = [heap[smallestChildIndex], heap[nodeIndex]];
        let highlightColor = 'red';
        drawHeap(heap, document.getElementById('canvas'));
        requestAnimationFrame(() => {
          let ctx = document.getElementById('canvas').getContext('2d');
          ctx.font = '12px Arial';
          ctx.textAlign = 'center';
          ctx.textBaseline = 'middle';
          ctx.fillStyle = highlightColor;
          ctx.fillText(min, 100 + (nodeIndex % 4) * 150, 200);
        });
        requestAnimationFrame(() => {
          let ctx = document.getElementById('canvas').getContext('2d');
          ctx.font = '12px Arial';
          ctx.textAlign = 'center';
          ctx.textBaseline = 'middle';
          ctx.fillStyle = 'black';
          ctx.fillText(min, 100 + (nodeIndex % 4) * 150, 200);
        });
        requestAnimationFrame(() => {
          let nodeIndex2 = smallestChildIndex;
          [heap[nodeIndex2], heap[nodeIndex]] = [heap[nodeIndex], heap[nodeIndex2]];
          drawHeap(heap, document.getElementById('canvas'));
        });
        await new Promise(resolve => globalThis.setTimeout(() => resolve(), 1000));
        nodeIndex = smallestChildIndex;
      } else {
        break;
      }
    }
  }
  extractMinCount++;
}

let canvas = document.createElement('canvas');
document.body.appendChild(canvas);
drawHeap(heap, canvas);

setInterval(() => {
  insertValue();
}, 2000);
setInterval(() => {
  extractMinValue();
}, 4000);
</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.
No usable answer reached the harness (ERR). Counted as a did-not-finish.
No usable answer reached the harness (ERR). Counted as a did-not-finish.
deepseek-r1:32bERRBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html><head><style>canvas{background:#1a1a1a;border:2px solid #333}body{display:flex;flex-direction:column;align-items:center;background:#000;color:#fff;font-family:sans-serif}</style></head><body>
<canvas id=c width=800 height=600></canvas>
<div>Inserts: <span id=i>0</span>, Extract-Mins: <span id=x>0</span></div>
<script>
const c=document.getElementById('c'),ctx=c.getContext('2d'),heap=[],inserts=document.getElementById('i'),extracts=document.getElementById('x');
let animQueue=[],currentNode=0,inserting=true,extracting=false;

class Node{
constructor(v){this.value=v;this.x=0;this.y=0;}

draw(){
ctx.beginPath();
ctx.arc(this.x,this.y,25,0,Math.PI*2);
ctx.fillStyle='#333';
ctx.fill();
ctx.strokeStyle='#fff';
ctx.stroke();
ctx.font='20px sans-serif';
ctx.textAlign='center';
ctx.fillText(this.value,this.x,this.y+10);
}

moveTo(x,y){
this.x=x;
this.y=y;
}
}

function drawLine(p,c){
ctx.beginPath();
ctx.moveTo(p.x,p.y);
ctx.lineTo(c.x,c.y);
ctx.strokeStyle='#555';
ctx.lineWidth=2;
ctx.stroke();
}

function calculatePositions(parent,level=1){
if(!parent) return;
const left=heap[2*currentNode];
const right=heap[2*currentNode+1];
if(left){
left.x=parent.x-60*(Math.pow(2,3-level));
left.y=parent.y+50;
calculatePositions(left,level+1);
}
if(right){
right.x=parent.x+60*(Math.pow(2,3-level));
right.y=parent.y+50;
calculatePositions(right,level+1);
}
}

function drawHeap(){
ctx.clearRect(0,0,c.width,c.height);
heap.forEach(node=>node.draw());
for(let i=0;i<heap.length/2;i++){
const node=heap[i];
if(heap[2*i]) drawLine(node,heap[2*i]);
if(heap[2*i+1]) drawLine(node,heap[2*i+1]);
}
}

function animateMove(node,x,y){
currentNode=heap.indexOf(node);
animQueue.push({node,x,y});
requestAnimationFrame(render);
}

function render(){
if(animQueue.length){
const {node,x,y}=animQueue.shift();
node.moveTo(x,y);
drawHeap();
}
}

function bubbleUp(index){
let parentIndex=Math.floor((index-1)/2);
while(parentIndex>=0 && heap[index].value<heap[parentIndex].value){
animQueue.push({action:'swap',from:index,to:parentIndex});
[heap[index],heap[parentIndex]]=[heap[parentIndex],heap[index]];
drawHeap();
render();
index=parentIndex;
parentIndex=Math.floor((index-1)/2);
}

calculatePositions(heap[0]);
animateMove(heap[index],heap[index].x,heap[index].y);
}

function sinkDown(index){
let left=2*index+1,right=left+1,minChild=index;
if(left<heap.length && heap[left].value < heap[minChild].value) minChild=left;
if(right<heap.length && heap[right].value < heap[minChild].value) minChild=right;

if(minChild!==index){
animQueue.push({action:'swap',from:index,to:minChild});
[heap[index],heap[minChild]]=[heap[minChild],heap[index]];
drawHeap();
render();
sinkDown(minChild);
}
}

function insert(value){
heap.push(new Node(value));
bubbleUp(heap.length-1);
inserts.textContent=parseInt(inserts.textContent)+1;
if(parseInt(extracts.textContent)*3 < parseInt(inserts.textContent)) extractMin();
}

function extractMin(){
if(!heap.length) return resetHeap();

extracts.textContent=parseInt(extracts.textContent)+1;
const min=heap[0].value;
heap[0]=heap.pop();
sinkDown(0);

document.body.innerHTML+=`<div style="color:#fff;text-align:center;">Extracted: ${min}</div>`;
setTimeout(()=>{
document.body.lastChild.remove();
},2000);
}

function resetHeap(){
heap.length=0;
inserts.textContent='0';
extracts.textContent='0';
currentNode=0;
drawHeap();
}

for(let i=0;i<500;i++) insert(Math.floor(Math.random()*100));
</script></body>
</html>
```
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><html lang="en"><head><meta charset="utf-8"><title>Binary Min-Heap</title>
<style>html,body{margin:0;height:100%;background:#0b0f1c;color:#e6ecff;font:14px system-ui,sans-serif;display:flex;align-items:center;justify-content:center}canvas{background:#131a30;border-radius:14px;box-shadow:0 10px 50px #0009;max-width:98vw}</style></head><body>
<canvas id="c"></canvas>
<script>
const W=920,H=520,c=document.getElementById('c'),x=c.getContext('2d'),dpr=window.devicePixelRatio||1;
c.width=W*dpr;c.height=H*dpr;c.style.width=W+'px';c.style.height=H+'px';x.scale(dpr,dpr);
let heap,ins,ext,anim,msg,mcol,hi,idle,mode,cur,pending;
function reset(){heap=[];anim=null;hi=-1;idle=.5;mode='ins';cur=-1;pending=3+(Math.random()*3|0);msg='fresh empty heap';mcol='#8fa3cc';if(ins===undefined){ins=0;ext=0;}}
reset();
function base(i){const d=Math.floor(Math.log2(i+1)),n=1<<d,p=i-(n-1);return[W*(p+.5)/n,72+d*82];}
function pos(i){if(anim){const A=base(anim.a),B=base(anim.b),k=anim.t,t=k<.5?2*k*k:1-2*(1-k)*(1-k);if(i===anim.a)return[A[0]+(B[0]-A[0])*t,A[1]+(B[1]-A[1])*t];if(i===anim.b)return[B[0]+(A[0]-B[0])*t,B[1]+(A[1]-B[1])*t];}return base(i);}
function next(){
 if(mode==='ins'){
  if(cur<0){
   if(pending<=0){mode='ext';idle=.35;return;}
   const v=2+(Math.random()*97|0);heap.push(v);ins++;pending--;cur=heap.length-1;hi=cur;
   msg='insert '+v+' as new leaf';mcol='#7ef0c0';idle=.4;return;}
  const p=(cur-1)>>1;
  if(cur>0&&heap[cur]<heap[p]){msg='bubble up: '+heap[cur]+' < '+heap[p]+' → swap';mcol='#7ef0c0';anim={a:cur,b:p,t:0};return;}
  msg='heap property restored';mcol='#8fa3cc';cur=-1;hi=-1;idle=.35;return;}
 if(cur<0){
  if(!heap.length){reset();return;}
  const m=heap[0];ext++;const last=heap.pop();
  msg='extract-min → '+m;mcol='#ffd166';
  if(heap.length){heap[0]=last;cur=0;hi=0;idle=.65;}
  else{cur=-1;hi=-1;mode='ins';pending=3+(Math.random()*3|0);idle=.7;}
  return;}
 const l=2*cur+1,r=l+1;let s=cur;
 if(l<heap.length&&heap[l]<heap[s])s=l;
 if(r<heap.length&&heap[r]<heap[s])s=r;
 if(s!==cur){msg='sink down: swap '+heap[cur]+' with smaller child '+heap[s];mcol='#ffd166';anim={a:cur,b:s,t:0};return;}
 cur=-1;hi=-1;mode='ins';pending=3+(Math.random()*3|0);idle=.45;
 msg='heap property restored';mcol='#8fa3cc';
 if(heap.length>26)reset();}
function circle(p,r){x.beginPath();x.arc(p[0],p[1],r,0,6.2832);}
function draw(){
 const g=x.createLinearGradient(0,0,0,H);g.addColorStop(0,'#151d36');g.addColorStop(1,'#0f1428');
 x.fillStyle=g;x.fillRect(0,0,W,H);
 x.font='600 17px system-ui';x.fillStyle='#7fb0ff';x.fillText('Binary Min-Heap — insert & extract-min',20,30);
 x.font='13px system-ui';x.fillStyle='#8fa3cc';
 x.fillText('inserts: '+ins+'    extract-mins: '+ext+'    nodes: '+heap.length,20,52);
 x.strokeStyle='#2b3botched';
 x.strokeStyle='#2b3a60';x.lineWidth=2;
 for(let i=1;i<heap.length;i++){const a=pos(i),b=pos((i-1)>>1);x.beginPath();x.moveTo(a[0],a[1]);x.lineTo(b[0],b[1]);x.stroke();}
 const R=heap.length>15?17:20;
 for(let i=0;i<heap.length;i++){
  const p=pos(i),act=anim?(i===anim.a||i===anim.b):(i===hi);
  x.save();
  if(act){x.shadowColor='#ffb03a';x.shadowBlur=22;}
  circle(p,R);x.fillStyle=act?'#ffb03a':(i===0?'#3d7bff':'#25335c');x.fill();
  x.shadowBlur=0;x.lineWidth=2;x.strokeStyle=act?'#ffe0a0':'#4a5f96';x.stroke();
  x.restore();
  x.fillStyle=act?'#241703':'#e9f0ff';x.font='600 '+(R>18?14:12)+'px system-ui';
  x.textAlign='center';x.textBaseline='middle';x.fillText(String(heap[i]),p[0],p[1]+1);
  x.textAlign='left';x.textBaseline='alphabetic';}
 if(!heap.length){x.fillStyle='#55648c';x.font='15px system-ui';x.textAlign='center';x.fillText('empty heap',W/2,H/2);x.textAlign='left';}
 x.fillStyle=mcol;x.font='600 15px system-ui';x.fillText(msg,20,H-24);
 x.fillStyle=mode==='ins'?'#7ef0c0':'#ffd166';circle([W-32,H-29],7);x.fill();
 x.fillStyle='#8fa3cc';x.font='12px system-ui';x.textAlign='right';
 x.fillText(mode==='ins'?'INSERT PHASE':'EXTRACT PHASE',W-48,H-24);x.textAlign='left';}
let prev=0;
function loop(ts){
 const dt=Math.min(.05,prev?(ts-prev)/1000:0);prev=ts;
 if(anim){anim.t+=dt/.4;
  if(anim.t>=1){const a=anim.a,b=anim.b,t=heap[a];heap[a]=heap[b];heap[b]=t;cur=b;hi=b;anim=null;idle=.22;}}
 else if(idle>0)idle-=dt;else next();
 draw();requestAnimationFrame(loop);}
requestAnimationFrame(loop);
</script></body></html>
GPT-5.5 (Codex)frontier referenceERRBLANK
Show code
<html><head><meta charset="utf-8"><title>Heap</title><style>html,body{margin:0;height:100%;background:#10141b;color:#e8eef8;font:16px system-ui;overflow:hidden}#hud{position:fixed;top:12px;left:12px;background:#0008;padding:10px 12px;border:1px solid #ffffff22;border-radius:8px;line-height:1.5}canvas{display:block;width:100vw;height:100vh}</style></head><body><canvas id="c"></canvas><div id="hud"></div><script>
const c=document.getElementById("c"),x=c.getContext("2d"),h=document.getElementById("hud");
let a=[],ins=0,ext=0,phase="insert",steps=[],mov=null,hi=[],out="",pause=0,last=0,done=0;
function fit(){c.width=innerWidth*devicePixelRatio;c.height=innerHeight*devicePixelRatio;x.setTransform(devicePixelRatio,0,0,devicePixelRatio,0,0)}onresize=fit;fit();
function val(){return 5+Math.floor(Math.random()*94)}
function pos(n,w=c.width/devicePixelRatio,H=c.height/devicePixelRatio){
 let m=[],top=95,gap=86;
 for(let i=0;i<n;i++){let d=Math.floor(Math.log2(i+1)),s=1<<d,k=i-s+1,y=top+d*gap,sp=w/(s+1);m[i]={x:sp*(k+1),y}}
 return m
}
function draw(t){
 let p=pos(a.length),W=c.width/devicePixelRatio,H=c.height/devicePixelRatio;
 x.clearRect(0,0,W,H);
 x.fillStyle="#10141b";x.fillRect(0,0,W,H);
 x.strokeStyle="#5f6f86";x.lineWidth=3;
 for(let i=1;i<a.length;i++){let q=Math.floor((i-1)/2);if(!p[i]||!p[q])continue;x.beginPath();x.moveTo(p[q].x,p[q].y);x.lineTo(p[i].x,p[i].y);x.stroke()}
 if(mov){
  let e=Math.min(1,(t-mov.t)/650),u=e<.5?2*e*e:1-Math.pow(-2*e+2,2)/2;
  if(p[mov.i]&&p[mov.j]){let A=p[mov.i],B=p[mov.j];p[mov.i]={x:A.x+(B.x-A.x)*u,y:A.y+(B.y-A.y)*u};p[mov.j]={x:B.x+(A.x-B.x)*u,y:B.y+(A.y-B.y)*u}}
 for(let i=0;i<a.length;i++){let r=22,o=p[i];if(!o)continue,0;x.beginPath();x.arc(o.x,o.y,r,0,7);let z=hi.includes(i);x.fillStyle=z?"#f5b84b":"#d8edf2";x.fill();x.strokeStyle=z?"#fff3b0":"#203040";x.stroke();x.fillStyle="#111820";x.font="700 15px system-ui";x.textAlign="center";x.textBaseline="middle";x.fillText(a[i],o.x,o.y)}
 h.innerHTML="inserts: "+ins+"<br>extract-mins: "+ext+"<br>removed: "+(out||"-")+"<br>size: "+a.length
}
function makeInsert(){
 let v=val();a.push(v);ins++;let i=a.length-1;steps=[{p:[i]}];
 while(i>0){let q=(i-1)>>1;if(a[i]>=a[q])break;steps.push({s:[i,q]});[a[i],a[q]]=[a[q],a[i]];i=q}
 steps.push({p:[i]});phase="insert"
}
function makeExtract(){
 if(!a.length){phase="insert";return}
 out=a[0];ext++;if(a.length==1){a.pop();steps=[{p:[]}];return}
 a[0]=a.pop();let i=0;steps=[{p:[0]}];
 for(;;){let l=i*2+1,r=l+1,m=i;if(l<a.length&&a[l]<a[m])m=l;if(r<a.length&&a[r]<a[m])m=r;if(m==i)break;steps.push({s:[i,m]});[a[i],a[m]]=[a[m],a[i]];i=m}
 steps.push({p:[i]});phase="extract"
}
function plan(){
 if(a.length==0||a.length>45){a=[];out="";done=0;phase="insert"}
 if(phase=="insert"){makeInsert();done++;if(done>5&&a.length>3&&Math.random()<.38){phase="extract";done=0}}
 else{makeExtract();done++;if(done>1+Math.random()*2||a.length<2){phase="insert";done=0}}
}
function step(t){
 if(pause&&t<pause)return;
 if(mov&&t-mov.t<650)return;
 if(mov){let i=mov.i,j=mov.j;[a[i],a[j]]=[a[j],a[i]];mov=null;pause=t+280;return}
 if(!steps.length){plan();pause=t+450;return}
 let z=steps.shift();hi=z.p||z.s||[];if(z.s)mov={i:z.s[0],j:z.s[1],t}
}
function loop(t){if(!last)last=t;step(t);draw(t);requestAnimationFrame(loop)}
for(let i=0;i<3;i++){a.push(val());ins++}a.sort((p,q)=>p-q);requestAnimationFrame(loop);
</script></body></html>
Claude Sonnet 5frontier referenceOK
Show code
<!doctype html><html><head><meta charset="utf-8"><title>Min-Heap Visualizer</title><style>
html,body{margin:0;padding:0;overflow:hidden;background:#0b1220;height:100%}
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;}
resize();addEventListener('resize',resize);

let heap=[];
let insCount=0, extCount=0;
let extractedMsg='', extractedTimer=0;
const MAX=14;

function sleep(ms){return new Promise(r=>setTimeout(r,ms));}
function rndVal(){return 1+Math.floor(Math.random()*99);}

function targetPos(i){
  const level=Math.floor(Math.log2(i+1));
  const levelStart=(1<<level)-1;
  const posInLevel=i-levelStart;
  const levelCount=1<<level;
  const x=W*(posInLevel+1)/(levelCount+1);
  const y=90+level*80;
  return {x,y};
}

function makeNode(v,cx,cy){return {value:v,cx,cy,hl:false};}

async function insertAnimated(v){
  const t=targetPos(heap.length);
  const node=makeNode(v,t.x,-30);
  heap.push(node);
  await sleep(250);
  let i=heap.length-1;
  while(i>0){
    const p=(i-1)>>1;
    if(heap[p].value>heap[i].value){
      const a=heap[i],b=heap[p];
      a.hl=b.hl=true;
      await sleep(350);
      heap[i]=b;heap[p]=a;
      await sleep(450);
      a.hl=false;b.hl=false;
      i=p;
    } else break;
  }
}

async function extractMinAnimated(){
  if(heap.length===0)return null;
  const removed=heap[0].value;
  heap[0].hl=true;
  await sleep(400);
  const last=heap.pop();
  if(heap.length>0){
    last.hl=false;
    heap[0]=last;
    await sleep(400);
    let i=0;
    while(true){
      const l=2*i+1,r=2*i+2;
      let s=i;
      if(l<heap.length&&heap[l].value<heap[s].value)s=l;
      if(r<heap.length&&heap[r].value<heap[s].value)s=r;
      if(s===i)break;
      const a=heap[i],b=heap[s];
      a.hl=b.hl=true;
      await sleep(350);
      heap[i]=b;heap[s]=a;
      await sleep(450);
      a.hl=false;b.hl=false;
      i=s;
    }
  }
  return removed;
}

async function main(){
  while(true){
    if(heap.length===0||heap.length>=MAX){
      heap=[];
      await sleep(500);
    }
    const n=2+Math.floor(Math.random()*3);
    for(let k=0;k<n;k++){
      if(heap.length>=MAX)break;
      await insertAnimated(rndVal());
      insCount++;
      await sleep(400);
    }
    if(heap.length>0){
      const v=await extractMinAnimated();
      extCount++;
      extractedMsg='Extracted min: '+v;
      extractedTimer=90;
      await sleep(700);
    }
  }
}
main();

function draw(){
  ctx.fillStyle='#0b1220';
  ctx.fillRect(0,0,W,H);
  for(let i=0;i<heap.length;i++){
    const node=heap[i];
    const t=targetPos(i);
    node.cx+=(t.x-node.cx)*0.15;
    node.cy+=(t.y-node.cy)*0.15;
  }
  ctx.strokeStyle='#3b4a63';
  ctx.lineWidth=2;
  for(let i=0;i<heap.length;i++){
    const l=2*i+1,r=2*i+2;
    if(l<heap.length){
      ctx.beginPath();ctx.moveTo(heap[i].cx,heap[i].cy);ctx.lineTo(heap[l].cx,heap[l].cy);ctx.stroke();
    }
    if(r<heap.length){
      ctx.beginPath();ctx.moveTo(heap[i].cx,heap[i].cy);ctx.lineTo(heap[r].cx,heap[r].cy);ctx.stroke();
    }
  }
  for(let i=0;i<heap.length;i++){
    const node=heap[i];
    ctx.beginPath();
    ctx.arc(node.cx,node.cy,24,0,Math.PI*2);
    ctx.fillStyle=node.hl?'#e2572b':(i===0?'#22a37a':'#2d6fe0');
    ctx.fill();
    ctx.strokeStyle='#dfe9f5';
    ctx.lineWidth=2;
    ctx.stroke();
    ctx.fillStyle='#fff';
    ctx.font='bold 15px sans-serif';
    ctx.textAlign='center';
    ctx.textBaseline='middle';
    ctx.fillText(String(node.value),node.cx,node.cy);
  }
  ctx.textAlign='left';
  ctx.fillStyle='#cfe0f5';
  ctx.font='16px sans-serif';
  ctx.fillText('Inserts: '+insCount+'   Extract-Min: '+extCount+'   Heap size: '+heap.length,20,30);
  if(extractedTimer>0){
    ctx.fillStyle='rgba(255,210,90,'+Math.min(1,extractedTimer/30)+')';
    ctx.font='bold 26px sans-serif';
    ctx.textAlign='center';
    ctx.fillText(extractedMsg,W/2,50);
    extractedTimer--;
  }
  requestAnimationFrame(draw);
}
draw();
</script>
</body></html>
Claude Fable 5frontier referenceOK
Show code
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>Min-Heap Animation</title>
<style>
html,body{margin:0;height:100%;background:#0d1420;overflow:hidden}
#i{position:fixed;top:10px;left:14px;color:#dfe8f5;font:bold 15px monospace;z-index:2}
canvas{display:block}
</style>
<div id="i"></div>
<canvas id="c"></canvas>
<script>
const cv=document.getElementById('c'),x=cv.getContext('2d'),info=document.getElementById('i');
let W,H;
function rs(){W=cv.width=innerWidth;H=cv.height=innerHeight}
rs();onresize=rs;
let heap=[],ins=0,ext=0,msg='',hl=-1,hl2=-1,extracted=null;
let waitT=0,tween=null,mv=null;
function pos(i){
 const d=Math.floor(Math.log2(i+1)),k=i-(2**d-1),n=2**d;
 return{x:W*(k+.5)/n,y:90+d*Math.min(95,(H-160)/4)};
}
function ease(t){t=Math.min(t,1);return t*t*(3-2*t)}
function*pause(t){waitT=t;while(waitT>0)yield}
function*doSwap(i,j){
 tween={i,j,t:0,dur:420};
 while(tween)yield;
 const tv=heap[i];heap[i]=heap[j];heap[j]=tv;
}
function*insert(){
 const v=1+(Math.random()*99|0);
 heap.push(v);ins++;
 let i=heap.length-1;
 hl=i;msg='insert '+v+' as new leaf';
 yield*pause(550);
 while(i>0){
  const p=(i-1)>>1;
  if(heap[i]<heap[p]){
   hl=i;hl2=p;msg='bubble-up: '+heap[i]+' < '+heap[p]+', swap';
   yield*pause(380);
   yield*doSwap(i,p);
   i=p;hl=i;hl2=-1;
   yield*pause(280);
  }else{msg='heap property holds';break}
 }
 hl=hl2=-1;
 yield*pause(350);
}
function*extract(){
 if(!heap.length)return;
 hl=0;msg='extract-min: remove root';
 yield*pause(600);
 extracted=heap[0];ext++;
 if(heap.length==1){
  heap.pop();hl=-1;
  yield*pause(900);extracted=null;return;
 }
 const li=heap.length-1,last=heap[li];
 heap[0]=null;heap.pop();
 msg='move last leaf '+last+' to root';
 mv={ai:li,v:last,t:0,dur:600};
 while(mv)yield;
 heap[0]=last;hl=0;
 yield*pause(400);
 let i=0;
 for(;;){
  const l=2*i+1,r=l+1;let s=i;
  if(l<heap.length&&heap[l]<heap[s])s=l;
  if(r<heap.length&&heap[r]<heap[s])s=r;
  if(s==i){msg='heap property holds';break}
  hl=i;hl2=s;msg='sink-down: swap '+heap[i]+' with smaller child '+heap[s];
  yield*pause(380);
  yield*doSwap(i,s);
  i=s;hl=i;hl2=-1;
  yield*pause(280);
 }
 hl=hl2=-1;
 yield*pause(700);
 extracted=null;
}
function*run(){
 for(;;){
  heap=[];extracted=null;hl=hl2=-1;
  msg='fresh empty heap';
  yield*pause(800);
  for(;;){
   const n=3+(Math.random()*3|0);
   for(let a=0;a<n&&heap.length<31;a++)yield*insert();
   const m=1+(Math.random()*2|0);
   for(let a=0;a<m&&heap.length;a++)yield*extract();
   if(heap.length==0){msg='heap empty - restarting';yield*pause(1000);break}
   if(heap.length>=31){msg='heap very large - resetting';yield*pause(1200);break}
  }
 }
}
const gen=run();
function node(px,py,v,fill,glow){
 x.beginPath();x.arc(px,py,21,0,7);
 x.fillStyle=fill;x.fill();
 x.lineWidth=glow?3:2;
 x.strokeStyle=glow?'#ffd28a':'#7fa8d9';
 x.stroke();
 x.fillStyle='#fff';x.textAlign='center';x.textBaseline='middle';
 x.font='bold 14px monospace';x.fillText(v,px,py+1);
}
function draw(){
 x.fillStyle='#0d1420';x.fillRect(0,0,W,H);
 x.strokeStyle='#33445f';x.lineWidth=2;
 for(let i=1;i<heap.length;i++){
  const p=(i-1)>>1;
  if(heap[i]==null||heap[p]==null)continue;
  const a=pos(i),b=pos(p);
  x.beginPath();x.moveTo(a.x,a.y);x.lineTo(b.x,b.y);x.stroke();
 }
 for(let i=0;i<heap.length;i++){
  if(heap[i]==null)continue;
  let p=pos(i);
  if(tween&&(i==tween.i||i==tween.j)){
   const o=i==tween.i?tween.j:tween.i,q=pos(o),k=ease(tween.t/tween.dur);
   p={x:p.x+(q.x-p.x)*k,y:p.y+(q.y-p.y)*k};
  }
  const f=i==hl?'#c2571a':i==hl2?'#1c6fb8':'#22344f';
  node(p.x,p.y,heap[i],f,i==hl||i==hl2);
 }
 if(mv){
  const a=pos(mv.ai),b=pos(0),k=ease(mv.t/mv.dur);
  node(a.x+(b.x-a.x)*k,a.y+(b.y-a.y)*k,mv.v,'#1c6fb8',1);
 }
 if(extracted!=null){
  x.fillStyle='#1b2b1b';
  x.fillRect(W/2-130,14,260,36);
  x.strokeStyle='#6fcf6f';x.lineWidth=2;
  x.strokeRect(W/2-130,14,260,36);
  x.fillStyle='#8fe88f';x.font='bold 17px monospace';
  x.textAlign='center';x.textBaseline='middle';
  x.fillText('extracted min: '+extracted,W/2,32);
 }
 info.textContent='inserts: '+ins+'   extract-mins: '+ext+'   size: '+heap.length+'   |  '+msg;
}
let lt=0;
function frame(ts){
 const dt=Math.min(ts-lt,50);lt=ts;
 if(tween){tween.t+=dt;if(tween.t>=tween.dur)tween=null}
 else if(mv){mv.t+=dt;if(mv.t>=mv.dur)mv=null}
 else if(waitT>0)waitT-=dt;
 else gen.next();
 draw();
 requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
</script>
</html>
Claude Haiku 4.5frontier referenceOKMINIFIED
Show code
<!DOCTYPE html><html><body style="margin:0;background:#333;display:flex;justify-content:center;align-items:center;height:100vh"><canvas id="c" width="800" height="600" style="background:#fff"></canvas><div id="i" style="position:absolute;top:10px;left:10px;color:#fff;font:14px Arial;font-weight:bold"></div><script>
const c=document.getElementById('c'),g=c.getContext('2d'),i=document.getElementById('i');let h=[],ins=0,ext=0,p='i',a=-1,x=-1;
function pos(n){const d=Math.log2(n+1)|0,s=(1<<d)-1;return{x:100+(n-s)*(600/(1<<d)),y:50+d*75}}
function dr(){g.fillStyle='#fff';g.fillRect(0,0,800,600);for(let n=1;n<h.length;n++){const pi=(n-1)>>1,cp=pos(n),pp=pos(pi);g.strokeStyle='#999';g.beginPath();g.moveTo(pp.x,pp.y);g.lineTo(cp.x,cp.y);g.stroke()}for(let n=0;n<h.length;n++){const po=pos(n);g.fillStyle=n===a?'#f00':n===x?'#ff0':'#0f0';g.beginPath();g.arc(po.x,po.y,20,0,6.28);g.fill();g.fillStyle='#000';g.font='bold 14px Arial';g.textAlign='center';g.textBaseline='middle';g.fillText(h[n],po.x,po.y)}i.textContent=`I:${ins}|E:${ext}`}
function b(k){a=k;const pi=(k-1)>>1;if(k>0&&h[k]<h[pi]){x=pi;dr();setTimeout(()=>{[h[k],h[pi]]=[h[pi],h[k]];a=-1;x=-1;b(pi)},500)}else{a=-1;x=-1;dr();setTimeout(op,300)}}
function s(k){a=k;let m=k;2*k+1<h.length&&h[2*k+1]<h[m]&&(m=2*k+1);2*k+2<h.length&&h[2*k+2]<h[m]&&(m=2*k+2);if(m!==k){x=m;dr();setTimeout(()=>{[h[k],h[m]]=[h[m],h[k]];a=-1;x=-1;s(m)},500)}else{a=-1;x=-1;dr();setTimeout(op,300)}}
function op(){if(h.length>50||h.length===0){h=[];ins=0;ext=0}if(p==='i'){h.push(Math.random()*100|0);ins++;dr();setTimeout(()=>b(h.length-1),300);p='e'}else{if(h.length>0){h[0]=h[h.length-1];h.pop();ext++;dr();if(h.length>0)setTimeout(()=>s(0),300);else setTimeout(op,300)}p='i'}}
dr();op();
</script></body></html>
Results at a glance— every model in this round with score, response time and status.

Who wrote what

ModelBlind scoreLatencyStatus
qwen3.5:9b 82.3 sOK
mistral-small:24b 176.2 sOK
gemma4:26b harness
qwen3-coder:30b 58.3 sOK
qwen3:14b 46.1 sOK
deepseek-r1:14b 32.0 sOK
llama3.1:8b 138.0 sOK
qwen3:8b harness
qwq:32b DNF
command-r:35b DNF
deepseek-r1:32b 64.8 sOK