Overview › Code › R68
Code · blind round

R68 · Edit-distance DP matrix with backtrace

blind round 9/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.

A frontier reference answered the same task (Claude Opus 5) — outside the field and deliberately unscored, further down the page.

Show task
Create ONE self-contained HTML file (STRICT LIMIT: max 120 lines total) that computes the Levenshtein edit distance between two fixed words of 8 to 10 letters and animates the dynamic-programming matrix on a <canvas>. Fill the matrix cell by cell, showing for each cell which of the three predecessors (insert, delete, substitute) won. When the matrix is complete, walk the backtrace from the bottom right to the top left as a highlighted path and print the resulting edit operations. 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:9bBLANKLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Levenshtein Matrix Animation</title>
    <style>body {display: flex; justify-content: center; align-items: flex-start; padding-top: 20px; background: #111; color: #eee;} canvas {border: 2px solid #555;}</style>
</head>
<body id="container">
    <canvas id="levCanvas" width="800" height="400"></canvas>
    <div id="output" style="margin-left: 30px; font-family: monospace; white-space: pre;"></div>

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

    const WORDS = ["kitten", "sitting"]; // Using 6 letters, acceptable for demonstration
    let M = WORDS[0].length;
    let N = WORDS[1].length;
    let matrix = Array(M + 1).fill(null).map(() => Array(N + 1).fill(0));
    let history = []; // Stores {r, c, cost, path} for animation

    let currentCell = { r: 0, c: 0 };
    let animating = true;
    let stepCounter = 0;
    let maxSteps = (M + 1) * (N + 1);

    function calculateDistance(r, c) {
        if (r === 0 || c === 0) return Math.max(r, c);
        
        const costSub = matrix[r - 1][c - 1] + (WORDS[0].charAt(r - 1) !== WORDS[1].charAt(c - 1) ? 1 : 0);
        const costDel = Math.min(matrix[r - 1][c] + 1, matrix[r][c - 1] + 1);

        if (costSub <= costDel) {
            return costSub;
        } else {
            return costDel;
        }
    }

    function calculatePath(r, c) {
        let minCost = Math.min(matrix[r - 1][c] + 1, matrix[r][c - 1] + 1);

        if (matrix[r - 1][c - 1] + (WORDS[0].charAt(r - 1) !== WORDS[1].charAt(c - 1) ? 1 : 0) <= minCost) {
            return "Substitute/Match";
        } else if (matrix[r - 1][c] + 1 < matrix[r][c - 1] + 1) {
             if (matrix[r - 1][c] + 1 < matrix[r - 1][c - 1] + (WORDS[0].charAt(r - 1) !== WORDS[1].charAt(c - 1) ? 1 : 0)) return "Delete";
             return "Insert"; // This logic is simplified for visualization, assuming a winner path.
        } else {
            return "Insert"; // Placeholder: must be the minimum of the three options.
        }
    }

    function resetMatrix() {
        matrix = Array(M + 1).fill(null).map(() => Array(N + 1).fill(0));
        history = [];
        currentCell = { r: 1, c: 1 };
        stepCounter = 0;
        animating = true;
        outputDiv.innerHTML = `Calculating Distance...`;
    }

    function drawMatrix() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        const cellW = canvas.width / (N + 1);
        const cellH = canvas.height / (M + 1);
        
        // Draw Grid and Labels
        for (let i = 0; i <= N; i++) {
            ctx.strokeStyle = '#333'; ctx.beginPath(); ctx.moveTo(i * cellW, 0); ctx.lineTo(i * cellW, canvas.height); ctx.stroke();
        }
        for (let j = 0; j <= M; j++) {
            ctx.strokeStyle = '#333'; ctx.beginPath(); ctx.moveTo(0, j * cellH); ctx.lineTo(canvas.width, j * cellH); ctx.stroke();
        }

        // Draw Content and Values
        for (let r = 0; r <= M; r++) {
            for (let c = 0; c <= N; c++) {
                const x = c * cellW + 10;
                const y = r * cellH + 10;

                ctx.fillStyle = '#222'; ctx.fillRect(x, y, cellW - 5, cellH - 5);
                ctx.strokeStyle = '#444'; ctx.strokeRect(x, y, cellW - 5, cellH - 5);

                let label = '';
                if (r === 0) {
                    label = 'Start';
                } else if (c === 0) {
                    label = 'Start';
                } else {
                     // Display the characters above and left of the current cell
                     ctx.fillStyle = '#aaa'; ctx.fillText(WORDS[0].charAt(r-1), x + 5, y - 10);
                     ctx.fillStyle = '#aaa'; ctx.fillText(WORDS[1].charAt(c-1), x + 5, y + cellH - 15);
                }

                if (matrix[r][c] !== undefined) {
                    let color = 'transparent';
                    if (history[r * (N+1) + c] && history[r * (N+1) + c].path === "Winner") {
                        color = '#4CAF50'; // Green for completed cells
                    } else if (r === 0 || c === 0) {
                         color = '#666'; // Initializing row/col
                    }
                    ctx.fillStyle = color;
                    ctx.fillText(matrix[r][c], x + 10, y + cellH / 2);

                } else {
                     // Drawing the current calculation step
                     if (r === currentCell.r && c === currentCell.c) {
                         ctx.fillStyle = '#FFD700'; // Yellow highlight
                         ctx.fillRect(x - 5, y - 5, cellW + 10, cellH + 10);
                     }
                }
            }
        }
    }

    function stepAnimation() {
        if (!animating) return;

        const r = currentCell.r;
        const c = currentCell.c;

        if (r > M || c > N) {
             // Matrix filling complete - Start Backtrace
            currentCell = { r: M, c: N };
            drawMatrix();
            setTimeout(backtrack, 100);
            return;
        }
        
        let cost = calculateDistance(r, c);
        matrix[r][c] = cost;

        // Record calculation history and path winner for visualization
        const currentHistoryEntry = { r: r, c: c, cost: cost };
        if (r > 0 && c > 0) {
            let minCost = Math.min(matrix[r - 1][c] + 1, matrix[r][c - 1] + 1, matrix[r - 1][c - 1] + (WORDS[0].charAt(r - 1) !== WORDS[1].charAt(c - 1) ? 1 : 0));
            currentHistoryEntry.path = "Winner"; // Simplified: just mark it as calculated
        } else if (r > 0 && c === 0) {
             currentHistoryEntry.path = "Delete";
        } else if (r === 0 && c > 0) {
             currentHistoryEntry.path = "Insert";
        }

        history[stepCounter] = currentHistoryEntry;

        // Move pointer
        if (c < N) {
            currentCell.c++;
        } else {
            currentCell.r++;
            currentCell.c = 1;
        }
        
        stepCounter++;
        drawMatrix();

        requestAnimationFrame(stepAnimation);
    }

    function backtrack() {
        let r = M;
        let c = N;
        let operations = [];

        while (r > 0 || c > 0) {
            if (r === 0 && c === 0) break;
            
            const cost = matrix[r][c];
            if (cost >= 0) { // Ensure we are at a calculated cell
                // Check for match/substitution winner
                const subCost = r > 0 && c > 0 ? Math.abs(matrix[r - 1][c - 1] + (WORDS[0].charAt(r - 1) !== WORDS[1].charAt(c - 1) ? 1 : 0) - cost) < 2 : Infinity;
                const delCost = r > 0 && c === 0 ? Math.abs(matrix[r - 1][c] + 1 - cost) < 2 : Infinity;
                const insCost = r === 0 && c > 0 ? Math.abs(matrix[r][c - 1] + 1 - cost) < 2 : Infinity;

                if (subCost <= 0 && r > 0 && c > 0) {
                    let op = WORDS[0].charAt(r-1) === WORDS[1].charAt(c-1) ? 'Match' : 'Substitute';
                    operations.unshift(`(${op}): ${WORDS[0].charAt(r-1)} -> ${WORDS[1].charAt(c-1)}`);
                    r--; c--;
                } else if (delCost <= 0 && r > 0) {
                    operations.unshift(`Delete: ${WORDS[0].charAt(r-1)}`);
                    r--;
                } else if (insCost <= 0 && c > 0) {
                     operations.unshift(`Insert: ${WORDS[1].charAt(c-1)}`);
                     c--;
                } else if (r > 0 && c > 0) {
                    // Fallback/Tie break logic - prioritize sub or delete
                    if (Math.min(matrix[r-1][c]+1, matrix[r][c-1]+1) == cost) {
                        operations.unshift("Error in Backtrace"); // Should not happen if calculation was perfect
                        break;
                    } else if (subCost <= 0) {
                         let op = WORDS[0].charAt(r-1) === WORDS[1].charAt(c-1) ? 'Match' : 'Substitute';
                         operations.unshift(`(${op}): ${WORDS[0].charAt(r-1)} -> ${WORDS[1].charAt(c-1)}`);
                         r--; c--;
                    } else if (delCost <= 0) {
                        operations.unshift(`Delete: ${WORDS[0].charAt(r-1)}`);
                        r--;
                    } else { // Must be insertion
                        operations.unshift(`Insert: ${WORDS[1].charAt(c-1)}`);
                        c--;
                    }
                }

            }
        }

        outputDiv.innerHTML = `--- OPERATIONS ---\n${operations.join('\n')}\n\n*** Finished! Restarting... ***`;
        setTimeout(() => { 
             M = WORDS[0].length; N = WORDS[1].length; 
             resetMatrix(); 
        }, 2500);
    }

    // Start the animation sequence immediately
    resetMatrix();
</script>
</body>
</html>
```
deepseek-r1:14bOKLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html>
<body style="background:#f0f0f0;">
<canvas id=c></canvas>
<div id=info></div>
<script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
let m, n, w, h;
let words = ["supercalifragilistic", "expialidocious"];
let dp, dir;

function start() {
    m = words[0].length;
    n = words[1].length;
    w = 45*(Math.max(m,n)+2);
    h = 35*(m+2);
    canvas.width = w; canvas.height = h;
    ctx.fillStyle = "#f0f0f0";
    ctx.fillRect(0,0,w,h);
    
    dp = Array.from({length: m+1}, ()=>Array(n+1).fill(0));
    dir = Array.from({length: m+1}, ()=>Array(n+1).fill(null));

    let step = 0;
    const totalSteps = (m+1)*(n+1);
    
    function fillCell(i,j) {
        if(i==m && j==n) return;
        let cost = 0;
        if(i==m) cost = dp[i][j+1]+1;
        else if(j==n) cost = dp[i+1][j]+1;
        else {
            if(words[0][i-1] == words[1][j-1]) cost = dp[i+1][j+1];
            else cost = dp[i+1][j+1]+1;
        }
        
        if(i<m && j<n) {
            if(dp[i+1][j+1] <= Math.min(cost, dp[i+1][j], dp[i][j+1])) dir[i][j]='S';
            else if(dp[i][j+1]<dp[i][j]) dir[i][j]='D';
            else dir[i][j]='I';
        }
        
        ctx.fillStyle = i%2==0 && j%2==0 ? "#4CAF50" : 
                        i%2==0 ? "#ff9800" : "#7a1Aff";
        ctx.fillRect(j*35+10, i*35+10, 30,30);
        
        if(i<m && j<n) {
            ctx.fillStyle = "white";
            ctx.font = "12px Arial";
            ctx.fillText( words[0][i-1], j*35+15, (i)*35+28 );
            ctx.fillText( words[1][j-1], j*35+15, (i+1)*35+28 );
        } else if(i<m) {
            ctx.fillText(" ", j*35+15, i*35+28);
        }
    }

    function animate() {
        if(step <= totalSteps) {
            fillCell(step%m, Math.floor(step/(m)));
            step++;
            requestAnimationFrame(animate);
        } else {
            drawPath();
            showResult();
        }
    }

    function drawPath() {
        ctx.beginPath();
        ctx.moveTo(w/2, h/2);
        let x = n, y = m;
        const pathSteps = [];
        
        while(x>0 || y>0) {
            if(dir[y][x]=='S') { 
                pathSteps.push({x: x*35+15, y: y*35+20});
                x--; y--;
            } else if(dir[y][x]=='D') {
                pathSteps.push({x: x*35+15, y: (y+1)*35+20});
                y--;
            } else {
                pathSteps.push({x: (x+1)*35+15, y: y*35+20});
                x++;
            }
        }

        let len = pathSteps.length;
        for(let i=0; i<len; i++) {
            ctx.lineTo(pathSteps[i].x, pathSteps[i].y);
        }
        ctx.strokeStyle = "#f44336";
        ctx.lineWidth = 2;
        ctx.stroke();
    }

    function showResult() {
        let editDistance = dp[m][n];
        let cost = (m+n - editDistance)*2;
        const ops = [];
        
        let x=0, y=0;
        while(x<m || y<n) {
            if(dir[y+1][x+1]=='S') {
                ops.push("Substitute");
                x++; y++;
            } else if(dir[y+1][x+1]=='D') {
                ops.push("Delete");
                y++;
            } else {
                ops.push("Insert");
                x++;
            }
        }

        let info = `Edit Distance: ${editDistance}<br>
                     Edit Cost : ${cost}<br>
                     Operations:
                     <ol>${ops.map((op,i)=>`<li>${op}</li>`).join("")}</ol>`;
        document.getElementById('info').innerHTML = info;
    }

    animate();
}

start();

setInterval(start, 3000);
</script>
</body>
</html>
```
mistral-small:24bSTATFORMAT
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>Levenshtein Edit Distance</title>
    <style>
        canvas { border: 1px solid black; }
    </style>
</head>
<body>
    <canvas id="levenshteinCanvas"></canvas>
    <script>
        const words = ['intention', 'execution'];
        const [word1, word2] = shuffle(words);
        const canvas = document.getElementById('levenshteinCanvas');
        const ctx = canvas.getContext('2d');
        canvas.width = 600;
        canvas.height = 400;

        function shuffle(array) {
            for (let i = array.length - 1; i > 0; i--) {
                const j = Math.floor(Math.random() * (i + 1));
                [array[i], array[j]] = [array[j], array[i]];
            }
            return array;
        }

        function drawMatrix(matrix) {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            const cellSize = 20;
            const offsetX = 50;
            const offsetY = 50;

            for (let i = 0; i < matrix.length; i++) {
                for (let j = 0; j < matrix[i].length; j++) {
                    ctx.strokeRect(offsetX + j * cellSize, offsetY + i * cellSize, cellSize, cellSize);
                    if (matrix[i][j] !== null) {
                        ctx.fillText(matrix[i][j], offsetX + j * cellSize + 5, offsetY + i * cellSize + 15);
                    }
                }
            }
        }

        function levenshtein(word1, word2) {
            const len1 = word1.length;
            const len2 = word2.length;
            const matrix = Array.from({ length: len1 + 1 }, () => Array(len2 + 1).fill(null));

            for (let i = 0; i <= len1; i++) {
                for (let j = 0; j <= len2; j++) {
                    if (i === 0) matrix[i][j] = { value: j, type: 'insert' };
                    else if (j === 0) matrix[i][j] = { value: i, type: 'delete' };
                    else {
                        const cost = word1[i - 1] === word2[j - 1] ? 0 : 1;
                        const options = [
                            { value: matrix[i - 1][j].value + 1, type: 'delete' },
                            { value: matrix[i][j - 1].value + 1, type: 'insert' },
                            { value: matrix[i - 1][j - 1].value + cost, type: word1[i - 1] === word2[j - 1] ? null : 'substitute' }
                        ];
                        const minOption = options.reduce((min, option) => (option.value < min.value ? option : min));
                        matrix[i][j] = { value: minOption.value, type: minOption.type };
                    }
                }
                drawMatrix(matrix);
            }

            return matrix;
        }

        function backtrace(matrix, word1, word2) {
            let i = word1.length;
            let j = word2.length;
            const operations = [];

            while (i > 0 || j > 0) {
                if (matrix[i][j].type === 'substitute' && word1[i - 1] !== word2[j - 1]) {
                    operations.push(`Substitute ${word1[i - 1]} with ${word2[j - 1]}`);
                    i--;
                    j--;
                } else if (matrix[i][j].type === 'delete') {
                    operations.push(`Delete ${word1[i - 1]}`);
                    i--;
                } else if (matrix[i][j].type === 'insert') {
                    operations.push(`Insert ${word2[j - 1]}`);
                    j--;
                }
            }
            return operations.reverse();
        }

        function animate(matrix, word1, word2) {
            const len1 = word1.length;
            const len2 = word2.length;

            let step = 0;
            const interval = setInterval(() => {
                if (step < len1 * len2 + 1) {
                    drawMatrix(matrix);
                    requestAnimationFrame(() => clearInterval(interval));
                } else {
                    const operations = backtrace(matrix, word1, word2);
                    alert(`Edit Operations: ${operations.join(', ')}`);
                }
            }, 50);
        }

        function start() {
            const matrix = levenshtein(word1, word2);
            animate(matrix, word1, word2);
        }

        start();
    </script>
</body>
</html>
```
qwen3:14bERRBLANKLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Levenshtein Animation</title>
    <style>
        body { display: flex; flex-direction: column; align-items: center; font-family: monospace; background: #111; color: #eee; }
        canvas { border: 2px solid #ccc; margin-top: 10px; background: #222; }
        #output { margin-top: 20px; padding: 10px; min-height: 50px; border: 1px dashed #444; width: 90%; max-width: 600px; }
    </style>
</head>
<body>

<canvas id="matrixCanvas" width="800" height="600"></canvas>
<div id="output">Initializing...</div>

<script>
const canvas = document.getElementById('matrixCanvas');
const ctx = canvas.getContext('2d');
let W1 = "JAVASCRIPT"; 
let W2 = "PYTHONCODE"; 
let M = []; // The DP matrix
let animating = true;
let currentCellX = 0;
let currentCellY = 0;
const N_ROWS = W2.length;
const N_COLS = W1.length;

ctx.font = "14px monospace";

function initializeMatrix() {
    M = Array(N_ROWS + 1).fill(null).map(() => Array(N_COLS + 1).fill(0));
    for (let i = 0; i <= N_ROWS; i++) M[i][0] = i;
    for (let j = 0; j <= N_COLS; j++) M[0][j] = j;
}

function drawCell(x, y, value) {
    const padding = 25;
    const cellWidth = (canvas.width - 2 * padding) / N_COLS;
    const cellHeight = (canvas.height - 2 * padding) / N_ROWS;
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    for (let i = 0; i <= N_ROWS; i++) {
        for (let j = 0; j <= N_COLS; j++) {
            const left = padding + j * cellWidth;
            const top = padding + i * cellHeight;
            ctx.fillStyle = '#333';
            ctx.fillRect(left, top, cellWidth, cellHeight);
            ctx.strokeStyle = '#555';
            ctx.strokeRect(left, top, cellWidth, cellHeight);

            ctx.fillStyle = (i === 0 && j === 0) ? 'black' : '#ddd';
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            ctx.fillText(value !== undefined ? value : '', left + cellWidth / 2, top + cellHeight / 2);

            if (i > 0 && j > 0) {
                const char1 = W2[i - 1];
                const char2 = W1[j - 1];
                // Add character identifiers above/left for clarity
                ctx.fillStyle = '#777';
                ctx.fillText(char1, left + cellWidth / 2, top - (cellHeight / 3));
                ctx.fillText(char2, left - (cellWidth / 3), top + cellHeight * 2;);
            }
        }
    }
}

function calculateAndAnimate() {
    if (!animating) return;

    // Check for termination condition: completed the matrix fill
    if (currentCellX > N_COLS && currentCellY > N_ROWS) {
       setTimeout(() => {
            animateBacktrace();
        }, 500);
        return;
    }

    let i = Math.floor(currentCellY / N_ROWS) * N_ROWS + (Math.ceil((currentCellY % N_ROWS) / 1));
    let j = Math.floor(currentCellX / N_COLS) * N_COLS + (Math.ceil((currentCellX % N_COLS) / 1));

    if (i <= N_ROWS && j <= N_COLS) {
        const cost = (W2[i - 1] === W1[j - 1]) ? 0 : 1;
        let minVal = Infinity;
        let winner = '';

        // Calculate the minimum cost and determine the path winner
        let deleteCost = M[i - 1][j] + 1;
        let insertCost = M[i][j - 1] + 1;
        let substituteCost = M[i - 1][j - 1] + (cost === 0 ? 0 : 1);

        minVal = Math.min(deleteCost, insertCost, substituteCost);
        M[i][j] = minVal;

        if (minVal === deleteCost) winner += 'D ';
        else if (minVal === insertCost) winner += 'I ';
        else if (minVal === substituteCost) winner += 'S ';

        // Redraw the matrix, highlighting the current cell and path winner
        drawCell(currentCellX + 1, currentCellY + 1, M[i][j]);
        ctx.fillStyle = '#FFD700'; // Gold highlight
        const padding = 25;
        const cellWidth = (canvas.width - 2 * padding) / N_COLS;
        const cellHeight = (canvas.height - 2 * padding) / N_ROWS;
        ctx.fillRect(padding + j * cellWidth, padding + i * cellHeight, cellWidth, cellHeight);

        // Display the winner operation
        document.getElementById('output').innerHTML = `(${W2[i-1]}${W1[j-1]}) Cost: ${minVal}. Winner: [${winner.trim()}].`;


        currentCellX++;
        if (currentCellX > N_COLS) {
            currentCellX = 0;
            currentCellY++;
        }

    } else {
        // Finished filling the matrix
        animating = false;
        return;
    }
}

function animateBacktrace() {
    let i = N_ROWS;
    let j = N_COLS;
    const path = [];
    let currentVal = M[i][j];

    while (i > 0 || j > 0) {
        path.unshift({ i, j });
        if (i === 0 && j === 0) break;
        
        // Determine the minimum cost predecessor that leads to M[i][j]
        let min = Infinity;
        let nextI = -1, nextJ = -1;

        // Check Diagonal (Substitute/Match)
        if (i > 0 && j > 0) {
            const cost = (W2[i - 1] === W1[j - 1]) ? 0 : 1;
            let subCost = M[i - 1][j - 1] + (cost === 0 ? 0 : 1);
            if (subCost < min) {
                min = subCost;
                nextI = i - 1;
                nextJ = j - 1;
            }
        }

        // Check Left (Insert)
        if (j > 0) {
            let insCost = M[i][j - 1] + 1;
            if (insCost < min) {
                min = insCost;
                nextI = i;
                nextJ = j - 1;
            } else if (Math.abs(insCost - min) < 0.01 && nextI === -1) { // Tie break priority: I > D > S
                 // If tied, prioritize movement that keeps the path visually balanced. We just need a consistent rule.
                if (nextI === i-1 && nextJ === j-1) {} // Already set by diagonal check
                else if (nextI === i-1 && nextJ === j) {} 
                else { nextI = i; nextJ = j - 1; }
            }
        }

        // Check Up (Delete)
        if (i > 0) {
            let delCost = M[i - 1][j] + 1;
            if (delCost < min) {
                min = delCost;
                nextI = i - 1;
                nextJ = j;
            } else if (Math.abs(delCost - min) < 0.01 && nextI === -1) {
                 // Tie break logic continuation
            }
        }

        i = Math.max(0, nextI);
        j = Math.max(0, nextJ);
    }


    let operationLog = [];
    for (let k = 1; k < path.length; k++) {
        const curr = path[k];
        const prev = path[k-1];
        const i = curr.i;
        const j = curr.j;

        if (i === prev.i - 1 && j === prev.j - 1) { // Diagonal move
            const cost = (W2[i - 1] === W1[j - 1]) ? 'Match' : 'Sub';
            operationLog.push(`(${cost})`);
        } else if (i === prev.i && j === prev.j - 1) { // Left move
            operationLog.push('Insert');
        } else if (i === prev.i - 1 && j === prev.j) { // Up move
            operationLog.push('Delete');
        }
    }

    document.getElementById('output').innerHTML = `<strong>--- BACKTRACE COMPLETE ---</strong><br>Operations: ${operationLog.join(' -> ')}<hr>Final Distance: ${M[N_ROWS][N_COLS]}`;

    // Loop the animation automatically
    setTimeout(() => {
        initializeMatrix();
        currentCellX = 0;
        currentCellY = 0;
        animating = true;
        requestAnimationFrame(animateStep);
    }, 2500); // Wait before restarting
}

function animateStep() {
    if (animating) {
        calculateAndAnimate();
        requestAnimationFrame(animateStep);
    } else {
        // This case should be handled by the backtrace timeout, but serves as a fallback.
    }
}


// Initialization run
initializeMatrix();
// Set initial state display
drawCell(0, 0, 0); 

// Start the animation loop
requestAnimationFrame(animateStep);

</script>
</body>
</html>
```
qwen3-coder:30bBLANKLIM
Show code
<!DOCTYPE html>
<html>
<head>
<title>Levenshtein Animation</title>
<style>
    body { background-color: #222; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; color: white; font-family: monospace; }
    canvas { border: 1px solid #555; background-color: #111; }
</style>
</head>
<body>
<canvas id="levCanvas" width="600" height="400"></canvas>

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

let wordA = "algorithm"; 
let wordB = "logarithm";
let m, n; // Dimensions
let matrix, operations;
let step = 0;
let currentStage = 'INIT'; // INIT -> FILLING -> BACKTRACING

// Initialize state
function init() {
    m = wordA.length;
    n = wordB.length;
    matrix = Array(m + 1).fill(0).map(() => Array(n + 1).fill(0));
    operations = Array(m + 1).fill(0).map(() => Array(n + 1).fill(''));
    step = 0;
    currentStage = 'INIT';
    drawCanvas();
    requestAnimationFrame(animate);
}

// Draw the static grid structure
function drawCanvas() {
    ctx.fillStyle = '#111';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.strokeStyle = '#333';
    ctx.lineWidth = 1;

    const CELL_W = (canvas.width - (m * 2)) / (n + 1) / n; // Approximate width calculation for alignment
    const CELL_H = canvas.height / (m + 1);
    
    // Simple proportional grid drawing based on cell count
    for(let i = 0; i <= m; i++) {
        ctx.beginPath();
        ctx.moveTo(0, i * CELL_H + 20);
        ctx.lineTo(canvas.width, i * CELL_H + 20);
        ctx.stroke();
    }
     for(let j = 0; j <= n; j++) {
        ctx.beginPath();
        ctx.moveTo(j * (canvas.width / (n+1)), 0);
        ctx.lineTo(j * (canvas.width / (n+1)), canvas.height);
        ctx.stroke();
    }

    // Labeling A and B
    ctx.fillStyle = '#aaa';
    ctx.fillText(`A (${wordA})`, 20, 30);
    ctx.fillText(`B (${wordB})`, 20, canvas.height - 10);
}

// Calculate the minimum cost and store the operation type
function calculate(i, j) {
    if (i === 0 || j === 0) return 0;

    const cost = wordA[i - 1] === wordB[j - 1] ? 0 : 1;
    
    let minVal = matrix[i - 1][j] + 1; // Deletion (Up)
    let deleteOp = 'DEL';

    if (matrix[i][j - 1] + 1 < minVal) {
        minVal = matrix[i][j - 1] + 1;
        deleteOp = 'INS';
    }

    const subCost = matrix[i - 1][j - 1] + cost; // Substitution/Match (Diagonal)
    if (subCost < minVal) {
        minVal = subCost;
        operations[i][j] = (cost === 0) ? 'MATCH' : 'SUB';
    } else if (subCost === minVal && operations[i - 1][j - 1] !== 'N/A') {
        // Tie-breaker logic to ensure we record a preferred operation type when tied
        if (!operations[i][j]) {
             operations[i][j] = (cost === 0) ? 'MATCH' : 'SUB';
        }
    }

    matrix[i][j] = minVal;
}

// Main filling logic
function fillStep() {
    if (step > m * n) return false; // Finished filling
    
    let i, j;
    
    // Simple row-major order traversal for the animation
    for(let r=1; r<=m; r++) {
        for(let c=1; c<=n; c++) {
            if (step === 0) return false; // Safety check

            i = r; j = c;
            if (r > 0 && c > 0) {
                calculate(i, j);
                // Immediately draw the filled cell state for animation feedback
                drawCell(i, j, matrix[i][j], operations[i][j]);
                step++;
            }
        }
    }
    return true; // Indicates successful full fill
}

// Backtracing logic (Executed after filling)
function backtraceStep() {
    if (currentStage !== 'INIT') return false; 

    let i = m;
    let j = n;

    while (i > 0 || j > 0) {
        let op = '';
        let cost = matrix[i][j];

        // Base cases for the edges
        if (i === 0 && j === 0) break;
        if (i === 0) { // Only Ins possible
            op = 'INS';
            matrix[i][j] -= 1; // Pretend to calculate cost difference
            j--;
        } else if (j === 0) { // Only Del possible
            op = 'DEL';
            matrix[i][j] -= 1;
            i--;
        } else {

            // Check the operations recorded during filling, or re-evaluate costs
            let currentOp = operations[i][j];

            if (currentOp === 'MATCH') {
                op = 'MATCH';
                matrix[i][j] -= 0;
                i--; j--;
            } else if (currentOp === 'SUB') {
                op = 'SUB';
                // Check which direction led to the minimum cost path
                let upCost = matrix[i-1][j] + 1;
                let leftCost = matrix[i][j-1] + 1;
                let diagCost = matrix[i-1][j-1] + (wordA[i-1] === wordB[j-1] ? 0 : 1);

                if (diagCost <= upCost && diagCost <= leftCost) {
                    op = 'SUB';
                    matrix[i][j] -= (wordA[i-1] === wordB[j-1] ? 0 : 1);
                    i--; j--;
                } else if (upCost < leftCost) {
                    // Move up (Delete)
                    op = 'DEL';
                    matrix[i][j] -= 1;
                    i--;
                } else {
                    // Move left (Insert)
                    op = 'INS';
                    matrix[i][j] -= 1;
                    j--;
                }
            } else if (!currentOp && i > 0 && j > 0) { // Fallback check for the corner case where operations might not have been fully recorded due to complexity
                 let upCost = matrix[i-1][j] + 1;
                 let leftCost = matrix[i][j-1] + 1;
                 let diagCost = matrix[i-1][j-1] + (wordA[i-1] === wordB[j-1] ? 0 : 1);

                if (diagCost <= upCost && diagCost <= leftCost) {
                    op = 'MATCH'; // Use match/sub for the pathing visualization
                    matrix[i][j] -= (wordA[i-1] === wordB[j-1] ? 0 : 1);
                    i--; j--;
                } else if (upCost < leftCost) {
                    op = 'DEL';
                    matrix[i][j] -= 1;
                    i--;
                } else {
                    op = 'INS';
                    matrix[i][j] -= 1;
                    j--;
                }
            } else {
                 // Edge case handling for the boundaries (must move)
                 if (i > 0 && j === 0) { op = 'DEL'; i--; }
                 else if (j > 0 && i === 0) { op = 'INS'; j--; }
                 else break;
            }

        // Draw the operation path and update state for next step
        drawCell(i, j, matrix[i][j], op, true);
        if (op !== '') console.log(`Operation: ${op}`);
        
        step++; 

        if ((i === 0 && j === 0)) {
            currentStage = 'FINISHED';
            return false; // Stop looping
        }
    }
    return true;
}


// Drawing helper function (Simplified drawing based on grid coordinates)
function drawCell(r, c, val, op, isPath = false) {
    let cellX = c * (canvas.width / (n + 1));
    let cellY = r * (canvas.height / (m + 1));
    let w = canvas.width / (n + 1);
    let h = canvas.height / (m + 1);

    ctx.fillStyle = isPath ? '#FFD700' : '#333'; // Highlight path or default cell fill
    ctx.fillRect(cellX, cellY, w, h);
    ctx.strokeStyle = '#555';
    ctx.strokeRect(cellX, cellY, w, h);

    let text = val;
    if (op) {
        text = op[0]; // Show only the first letter of the operation type
    } else if (!isPath && r === 0 || c === 0) {
        // Leave top-left corner empty/default for boundary conditions
    }

    ctx.fillStyle = '#FFF';
    ctx.font = '14px monospace';
    ctx.textAlign = 'center';
    ctx.fillText(text, cellX + w / 2, cellY + h * 0.8);
}


// Animation loop
function animate() {
    if (currentStage === 'INIT') {
        drawCanvas(); // Draw the initial labels/grid structure
        setTimeout(() => {
            request
llama3.1:8bERRBLANKLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html>
<head>
<title>Levenshtein Animation</title>
<style>
body { margin: 10px; }
#canvas { border: 1px solid black; }
</style>
</head>
<body>
<script>
const canvas = document.createElement('canvas');
canvas.width = 400;
canvas.height = 200;
document.body.appendChild(canvas);

const ctx = canvas.getContext('2d');

function levenshtein(s, t) {
  const m = s.length + 1;
  const n = t.length + 1;
  const d = new Array(m).fill(0).map(() => new Array(n).fill(0));

  for (let i = 0; i < m; i++) d[i][0] = i;
  for (let j = 0; j < n; j++) d[0][j] = j;

  for (let i = 1; i < m; i++) {
    for (let j = 1; j < n; j++) {
      const cost = s[i - 1] === t[j - 1] ? 0 : 1;
      d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
    }
  }

  return d[m - 1][n - 1];
}

function drawMatrix(s, t) {
  const m = s.length + 1;
  const n = t.length + 1;
  const d = levenshtein(s, t);

  let x = 0;
  let y = 0;

  ctx.clearRect(0, 0, canvas.width, canvas.height);
  for (let i = 0; i < m; i++) {
    for (let j = 0; j < n; j++) {
      if (i === m - 1 && j === n - 1) break;
      const c = d[i][j];
      ctx.fillStyle = 'lightgray';
      ctx.fillRect(x, y, 30, 30);
      ctx.fillStyle = 'black';
      ctx.font = '12px Arial';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      let text;
      if (i < m - 1 && j === n - 1) {
        text = 'insert';
      } else if (j < n - 1 && i === m - 1) {
        text = 'delete';
      } else if (d[i][j] !== d[i + 1][j] && d[i][j] !== d[i][j + 1]) {
        text = 'substitute';
      }
      ctx.fillText(text, x + 15, y + 15);
      y += 30;
    }
    if (i < m - 1) {
      y = 0;
      x += 30;
    }
  }

  const backtrace = [];
  let i = m - 1;
  let j = n - 1;
  while (i > 0 || j > 0) {
    if (i < m - 1 && j === n - 1) {
      backtrace.push({ x: 15, y: y + 47.5, text: 'insert' });
      i++;
    } else if (j < n - 1 && i === m - 1) {
      backtrace.push({ x: x + 67.5, y: y + 47.5, text: 'delete' });
      j++;
    } else if (d[i][j] !== d[i + 1][j] && d[i][j] !== d[i][j + 1]) {
      backtrace.push({ x: x + 15 + i * 30 - 15, y: y + 47.5, text: 'substitute' });
      if (d[i][j] === d[i + 1][j]) j++;
      else i++;
    }
    y += 30;
    if (i < m - 1) {
      y = 0;
      x += 30;
    }
  }

  backtrace.reverse();

  ctx.clearRect(0, canvas.height - 50, canvas.width, 50);
  for (let i = 0; i < backtrace.length; i++) {
    const { x: left, y: top, text } = backtrace[i];
    ctx.fillStyle = 'lightgray';
    ctx.fillRect(left, top, 30, 20);
    ctx.fillStyle = 'black';
    ctx.font = '12px Arial';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(text, left + 15, top + 10);
  }

  const ops = [];
  for (let i = 0; i < backtrace.length; i++) {
    const { text } = backtrace[i];
    if (text !== 'substitute' || i === 0) ops.push(text);
  }
  ctx.clearRect(0, canvas.height - 50, canvas.width, 20);
  ctx.fillStyle = 'black';
  ctx.font = '12px Arial';
  ctx.textAlign = 'left';
  ctx.textBaseline = 'top';
  const opText = ops.join(', ');
  ctx.fillText(opText, 10, canvas.height - 30);

  requestAnimationFrame(() => drawMatrix(s, t));
}

const s = 'paragraph';
const t = 'paragraphs';

drawMatrix(s, t);
</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 (THIN) — 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.
deepseek-r1:32bBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html>
<head><title>Levenshtein Animation</title></head>
<body style="background:#f0f0f0;display:flex;flex-direction:column;align-items:center;">
<canvas id="matrix" width="540" height="360"></canvas>
<div id="edits" style="width:500;margin-top:1em;padding:10px;background:white;border-radius:5px;"></div>

<script>
const word1 = "substitute";
const word2 = "replacement";
let edits = [];
const canvas = document.getElementById('matrix');
const ctx = canvas.getContext('2d');
const m = word1.length, n = word2.length;
let dp = Array(m+1).fill().map(() => Array(n+1));
let i=0,j=0;

function init() {
  dp[0][0] = {cost:0};
  for(let x=0; x<=m;x++) for(let y=0;y<=n;y++) if(x==0 || y==0) dp[x][y] = {cost:x+y};
}

function drawMatrix() {
  let cellWidth = canvas.width / (Math.max(m,n)+1);
  ctx.strokeStyle = '#ccc';
  
  for(let x=0; x<=m+1; x++) {
    ctx.beginPath();
    ctx.moveTo(x*cellWidth, 0);
    ctx.lineTo(x*cellWidth, canvas.height);
    ctx.stroke();
  }
  
  for(let y=0; y<=n+1; y++) {
    ctx.beginPath();
    ctx.moveTo(0, y*(canvas.height/(n+1)));
    ctx.lineTo(canvas.width, y*(canvas.height/(n+1)));
    ctx.stroke();
  }
}

function fillCell(x,y,color,text) {
  let cellWidth = canvas.width / (Math.max(m,n)+1);
  let cellHeight = canvas.height / (n+1);
  
  ctx.fillStyle = color;
  ctx.fillRect(x*cellWidth, y*cellHeight, cellWidth-2, cellHeight-2);
  
  if(text) {
    ctx.fillStyle = '#000';
    ctx.font = '14px Arial';
    ctx.fillText(text, x*cellWidth+5, y*cellHeight + cellHeight/2 +7);
  }
}

function updateMatrix() {
  let cellWidth = canvas.width / (Math.max(m,n)+1);
  
  if(i <= m && j <= n) {
    if(i >0 || j>0) {
      let costInsert = dp[i][j-1].cost+1;
      let costDelete = dp[i-1][j].cost+1;
      let costReplace = dp[i-1][j-1].cost + (word1[i-1] == word2[j-1] ? 0 : 1);
      
      let minCost = Math.min(costInsert, costDelete, costReplace);
      dp[i][j] = {cost:minCost};
      
      if(costInsert === minCost) {
        edits.push({type:'insert', char:word2[j-1], x:i, y:j});
      }
      if(costDelete === minCost) {
        edits.push({type:'delete', char:word1[i-1], x:i, y:j});
      }
      if(costReplace === minCost && word1[i-1] != word2[j-1]) {
        edits.push({type:'replace', from:word1[i-1], to:word2[j-1], x:i, y:j});
      }
    }

    fillCell(i,j,'#bfb', dp[i][j].cost);
    
    if(j < n) {
      j++;
    } else if(i < m) {
      i++;
      j=0;
    } else {
      requestAnimationFrame(startBacktrace);
      return;
    }
  }
  
  requestAnimationFrame(updateMatrix);
}

function startBacktrace() {
  let x = m, y = n;
  const path = [];
  
  while(x > 0 || y > 0) {
    if(y > 0 && (dp[x][y].cost === dp[x][y-1].cost + 1)) {
      path.push({type:'insert', char:word2[y-1], x:x, y:y});
      y
qwq:32bBLANKFORMAT
Show code
<think>

Okay, I need to create a self-contained HTML file that calculates the Levenshtein edit distance between two fixed words of 8 to 10 letters and animate the dynamic programming matrix on a canvas. The animation should show each cell being filled, indicating which of the three predecessors (insert, delete, substitute) was chosen. After building the matrix, it should trace back the path from the bottom-right to the top-left, highlight the path, and list the edit operations. The animation must use requestAnimationFrame for smoothness, start immediately, and restart with new random words when done. No libraries, no comments, and strict line limit of 120 lines.

First, I need to pick two fixed words. Let's say "example" and "sample" – both 7 letters, but maybe I can make them longer. Wait, the user said 8-10 letters. Let me think of longer ones. Maybe "elephant" (8) and "pineapple" (9). Or "strawberry" (10) and "blueberry" (9). Let me choose two 8-letter words: "sunburnt" and "moonlight". Wait, need to make sure they can have a clear path when computing the edit operations. Maybe "kangaroo" (8) and "koala" (5 letters? No, too short). Hmm, perhaps better to use "elephant" and "pineapple". Let me just pick two 8-letter words.

Wait, the problem states that the words are fixed, but the user wants it to restart with a fresh random instance each time. Oh, the instruction says "two fixed words" but also "restart with a fresh random instance". Wait, maybe the problem says "two fixed words of 8 to 10 letters" but also the restart is with random instances? Wait the user's instruction says: "computes the Levenshtein edit distance between two fixed words of 8 to 10 letters". Wait, but then "restart with a fresh random instance when finished". So maybe the fixed words are placeholders, but in reality, the code should choose random words each time. Wait, perhaps the fixed words are just for the example, but the code needs to generate random words of 8-10 letters each time. Let me check the problem again.

The exact instruction says: "computes the Levenshtein edit distance between two fixed words of 8 to 10 letters". Oh, so the two words are fixed, but the code must generate random ones each time it restarts? Wait, no, the problem says "fixed words" but then says "restart with a fresh random instance". So maybe the user wants the code to pick two random 8-10 letter words each time it restarts. So the words aren't fixed, but each run uses a pair of random words. That makes more sense, so I need to generate two random words each time. Let me proceed with that.

So first, I'll need functions to generate random words of 8-10 letters. Letters can be lowercase, perhaps. So maybe a helper function to get a random letter, and then build a word of length between 8-10.

Then, the main part is the Levenshtein distance calculation with dynamic programming matrix. The animation must step through each cell calculation, showing the predecessors. The matrix is m x n where m is length of first word (word1) and n is word2.

The animation steps: each cell is filled one by one, showing which of the three options (insert, delete, substitute) was chosen (the minimum of the three). The order in which the cells are filled needs to be the order of the DP computation, which is row by row, left to right, top to bottom (except for the first row and first column which are initialized first). But the DP table is filled in a way that each cell (i,j) depends on (i-1,j), (i,j-1), (i-1,j-1). So for dynamic programming, the standard way is to compute row by row, filling each cell left to right. The first row and first column are the base cases (i.e., first row is 0,1,2,... for inserts, first column similarly for deletes).

So to animate, the steps would be:

1. Initialize the matrix with the first row and first column. These are steps 0 to m (for first column) and 0 to n (for first row). But since the animation is cell by cell, perhaps each cell's value is computed one by one. So first, show the first row (row 0), then the first column (column 0), but since they are all in row 0 and column 0, they can be filled first. Wait, actually in the standard DP matrix, the first row (row 0) goes from 0 to n, and the first column (column 0) goes from 0 to m. So when initializing, we can first fill row 0 and column 0. So maybe first step is to fill those.

Then, for each cell (i,j) where i and j are both >=1, compute their value based on the three predecessors.

The order in which the cells are filled would be in row-wise order. So for row 1, fill all cells from column 1 to column n, then row 2, etc.

Each step of animation would be one cell being filled. For each cell, the code must compute which of the three predecessors (up, left, or diagonal) contributed to the minimum value. The predecessor can be tracked by storing a direction (like arrows for backtrace).

Once the entire matrix is filled, the backtrace starts from (m,n) to (0,0), following the directions stored in the matrix. The path is traced, highlighting each step. The edit operations are determined based on the direction taken at each step (e.g., if moving up is a deletion, left is insertion, diagonal is substitution or same character).

The animation needs to be smooth with requestAnimationFrame, so each step (filling a cell or moving along the path) must be scheduled with requestAnimationFrame.

The overall structure would be:

- Canvas setup and context.
- Variables to track current step in the animation.
- The two words, generated randomly each time.
- The DP matrix's data (values and directions).
- Animate function that processes step by step, either filling the matrix or backtracing.

Let me think about the structure in code.

First, the HTML:

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Levenshtein Animation</title>
    <style>body{margin:0}canvas{background:#eee}</style>
  </head>
  <body>
    <canvas id="c"></canvas>
    <script>
    // code here
    </script>
  </body>
</html>
```

The script part will have all the logic.

First, variables:

- Words: let word1 and word2 be generated each time via a function.

Function to generate random words:

function randomWord() {
  const len = Math.floor(Math.random() * 3 + 8); // 8-10 letters
  return Array(len).fill().map(() => String.fromCharCode(97 + Math.random() * 26)).join('');
}

But maybe better to have a helper function.

But since the code must be self-contained, we'll need to have this inline.

Then, the main variables: canvas, context, words, the matrix (values and directions), current step,
command-r:35bERRBLANKLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Levenshtein Distance Animation</title>
    <style>
        body {
            margin: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #f4f4f4;
        }
        canvas {
            border: 1px solid #333;
            box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
        }
    </style>
</head>
<body>
    <canvas id="matrixCanvas"></canvas>

    <script>
        const words = [["rebellion", "reaction"], ["substitution", "suggestion"]];
        let wordIndex = Math.floor(Math.random() * words.length);
        const [word1, word2] = words[wordIndex];

        function min3(a, b, c) {
            return Math.min(Math.min(a, b), c);
        }

        function getColor(operation) {
            if (operation === "insert") return "#00ff00";
            if (operation === "delete") return "#ff0000";
            if (operation === "substitute") return "#ffff00";
            return "#ffffff";
        }

        function levenshteinAnimation() {
            const canvas = document.getElementById("matrixCanvas");
            const ctx = canvas.getContext("2d");

            wordIndex = (wordIndex + 1) % words.length;
            [word1, word2] = words[wordIndex];

            const len1 = word1.length;
            const len2 = word2.length;
            let matrix = Array.from({ length: len1 + 1 }, () => new Array(len2 + 1).fill(0));
            
            function drawCell(i, j) {
                ctx.fillStyle = getColor(matrix[i][j]);
                ctx.fillRect((j - i) * canvas.width / (len2 - len1 + 1), i * canvas.height / (len1 + 1), canvas.width / (len2 - len1 + 1), canvas.height / (len1 + 1));
            }

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

                for (let i = matrix.length - 1; i >= 0; i--) {
                    for (let j = matrix[i].length - 1; j >= 0; j--) {
                        if (i === matrix.length - 1)
                            matrix[i][j] = word2[j] === word1[i] ? 0 : 1;
                        else if (j === matrix[i].length - 1)
                            matrix[i][j] = i + 1;
                        else {
                            const insertCost = matrix[i][j + 1] + 1;
                            const deleteCost = matrix[i + 1][j] + 1;
                            const substituteCost = word2[j] === word1[i] ? matrix[i + 1][j + 1] : matrix[i + 1][j + 1] + 1;
                            matrix[i][j] = min3(insertCost, deleteCost, substituteCost);
                        }

                        drawCell(i, j);
                        
                    }
                }
            }

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

                if (matrix) {
                    const i = matrix[0].length - 1;
                    const j = matrix.length - 1;

                    while (i >= 0 && j >= 0) {
                        drawCell(j, i);

                        if ((word2[i] === word1[j]) || (matrix[j + 1][i + 1] < matrix[j][i])) {
                            ctx.fillStyle = getColor("substitute");
                            j--; i--;
                        } else if (matrix[j + 1][i + 1] > matrix[j + 1][i]) {
                            ctx.fillStyle = getColor("insert");
                            i--;
                        } else {
                            ctx.fillStyle = getColor("delete");
                            j--;
                        }

                        ctx.fillRect((i - j) * canvas.width / (len2 - len1 + 1), j * canvas.height / (len1 + 1), canvas.width / (len2 - len1 + 1), canvas.height / (len1 + 1));
                        ctx.fillStyle = "#ffffff";
                    }
                } else {
                    draw();

                    const editOps = [];
                    for (let i = matrix[0].length - 1, j = matrix.length - 1; i >= 0 && j >= 0;) {
                        if ((word2[i] === word1[j]) || (matrix[j + 1][i + 1] < matrix[j][i])) {
                            editOps.push(word2[i] !== word1[j] ? "substitute" : null);
                            j--; i--;
                        } else if (matrix[j + 1][i + 1] > matrix[j + 1][i]) {
                            editOps.push("insert");
                            i--;
                        } else {
                            editOps.push("delete");
                            j--;
                        }
                    }

                    console.log(editOps.filter(op => op).reverse().join(", "));
                }

                requestAnimationFrame(animate);
            }

            canvas.height = (matrix.length + 1) * canvas.height / matrix.length;
            animate();
        }

        document.addEventListener("DOMContentLoaded", levenshteinAnimation);
    </script>
</body>
</html>
```
Outside the Brain cluster — same task, same character budget, collected through their own tooling (response times not comparable)
GPT-5.5 (Codex)frontier referenceOK
Show code
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Levenshtein DP</title>
<style>
html,body{margin:0;height:100%;background:#101418;color:#e7eef7;font:15px system-ui}
body{display:grid;place-items:center}
#wrap{width:min(96vw,980px)}
canvas{width:100%;height:auto;background:#151b22;border:1px solid #354250}
#ops{min-height:4.8em;white-space:pre-wrap;margin-top:10px;color:#cfd9e4}
</style>
</head>
<body>
<div id="wrap"><canvas id="c" width="980" height="680"></canvas><div id="ops"></div></div>
<script>
const words=["distance","editing","matrixes","algorithm","function","variable","sequence","birthday","portable","notation","graphics","backtrace"];
const cvs=document.getElementById("c"),ctx=cvs.getContext("2d"),opsEl=document.getElementById("ops");
let A,B,D,win,order,path,ops,phase,i,last=0,hold=0;
function pick(){A=words[Math.random()*words.length|0];do B=words[Math.random()*words.length|0];while(B==A)}
function calc(){
let m=A.length,n=B.length;D=Array.from({length:m+1},()=>Array(n+1).fill(0));win=Array.from({length:m+1},()=>Array(n+1).fill(""));
for(let r=0;r<=m;r++)D[r][0]=r,win[r][0]="D";for(let c=0;c<=n;c++)D[0][c]=c,win[0][c]="I";
order=[];for(let r=1;r<=m;r++)for(let c=1;c<=n;c++){let sub=D[r-1][c-1]+(A[r-1]==B[c-1]?0:1),del=D[r-1][c]+1,ins=D[r][c-1]+1,min=Math.min(ins,del,sub);D[r][c]=min;win[r][c]=min==sub?"S":min==del?"D":"I";order.push([r,c])}
path=[];ops=[];let r=m,c=n;path.push([r,c]);while(r||c){let w=win[r][c];if(r&&c&&w=="S"){if(A[r-1]==B[c-1])ops.push("keep "+A[r-1]);else ops.push("substitute "+A[r-1]+" -> "+B[c-1]);r--;c--}else if(r&&(w=="D"||!c)){ops.push("delete "+A[r-1]);r--}else{ops.push("insert "+B[c-1]);c--}path.push([r,c])}ops.reverse()
}
function reset(){pick();calc();phase="fill";i=0;hold=0;opsEl.textContent="";last=0}
function arrow(w,x,y,s){ctx.fillStyle=w=="I"?"#63d2ff":w=="D"?"#ffb45f":"#7ee787";ctx.font=s*.32+"px system-ui";ctx.textAlign="center";ctx.textBaseline="middle";ctx.fillText(w=="I"?"←":w=="D"?"↑":"↖",x,y+s*.24)}
function draw(){
ctx.clearRect(0,0,cvs.width,cvs.height);let m=A.length,n=B.length,cols=n+2,rows=m+2,s=Math.min(68,880/cols,540/rows),ox=(980-s*cols)/2+s,oy=70;
ctx.fillStyle="#e7eef7";ctx.font="26px system-ui";ctx.textAlign="center";ctx.fillText(A+"  →  "+B,490,34);
ctx.font="18px system-ui";for(let c=1;c<=n;c++)ctx.fillText(B[c-1],ox+(c+1)*s+s/2,oy+s/2);for(let r=1;r<=m;r++)ctx.fillText(A[r-1],ox+s/2,oy+(r+1)*s+s/2);
let shown=phase=="fill"?i:order.length,seen=new Set(order.slice(0,shown).map(p=>p.join()));
if(phase!="fill")for(let k=0;k<=i&&k<path.length;k++)seen.add(path[k].join());
for(let r=0;r<=m;r++)for(let c=0;c<=n;c++){
let x=ox+(c+1)*s,y=oy+(r+1)*s,key=r+","+c,on=seen.has(key)||r==0||c==0,hi=phase!="fill"&&path.slice(0,i+1).some(p=>p[0]==r&&p[1]==c);
ctx.fillStyle=hi?"#ffd166":on?"#223142":"#18202a";ctx.strokeStyle="#3e5063";ctx.lineWidth=hi?4:1;ctx.fillRect(x,y,s,s);ctx.strokeRect(x,y,s,s);
if(on){ctx.fillStyle=hi?"#101418":"#e7eef7";ctx.font=s*.35+"px system-ui";ctx.fillText(D[r][c],x+s/2,y+s*.42);if(r&&c&&seen.has(key))arrow(win[r][c],x+s/2,y+s*.56,s)}
}
ctx.fillStyle="#aab8c6";ctx.font="17px system-ui";ctx.fillText("distance: "+D[m][n]+"   filling: "+Math.min(shown,order.length)+"/"+order.length,490,650)
}
function step(t){
if(!last)last=t;let dt=t-last;last=t;
if(phase=="fill"){i+=dt/95;if(i>=order.length){i=0;phase="trace";opsEl.textContent=ops.join("\n")}}
else{i+=dt/170;if(i>=path.length+10){hold+=dt;if(hold>900)reset()}}
draw();requestAnimationFrame(step)
}
reset();requestAnimationFrame(step);
</script>
</body>
</html>
Claude Sonnet 5frontier referenceOK
Show code
<!DOCTYPE html><html><head><meta charset="utf8"><title>Levenshtein</title><style>
body{margin:0;background:#111;color:#eee;font-family:monospace}canvas{display:block;margin:20px auto;background:#181818}
</style></head><body>
<canvas id="c" width="820" height="560"></canvas>
<script>
const cv=document.getElementById('c'),cx=cv.getContext('2d');
const words=[['carousel','flamingo'],['mountain','elephants'],['brighten','umbrella'],['sandwich','crocodile']];
let a,b,n,m,D,src,order,oi,phase,pause,path,pi,ops;
const cell=44,ox=140,oy=90;
function reset(){
 let pair=words[Math.floor(Math.random()*words.length)];
 a=pair[0];b=pair[1];n=a.length;m=b.length;
 D=[];src=[];
 for(let i=0;i<=n;i++){D.push(new Array(m+1).fill(-1));src.push(new Array(m+1).fill(''))}
 order=[];for(let i=0;i<=n;i++)for(let j=0;j<=m;j++)order.push([i,j]);
 oi=0;phase='fill';pause=0;path=[];pi=0;ops=[]
}
function fillOne(){
 let[i,j]=order[oi];
 if(i===0&&j===0){D[i][j]=0;src[i][j]='S'}
 else if(i===0){D[i][j]=j;src[i][j]='I'}
 else if(j===0){D[i][j]=i;src[i][j]='D'}
 else{
  let sub=D[i-1][j-1]+(a[i-1]===b[j-1]?0:1);
  let del=D[i-1][j]+1,ins=D[i][j-1]+1;
  let best=Math.min(sub,del,ins);
  D[i][j]=best;
  src[i][j]=best===sub?(a[i-1]===b[j-1]?'=':'X'):(best===del?'D':'I')
 }
 oi++;
 if(oi>=order.length){phase='backtrace';path=[[n,m]]}
}
function backOne(){
 let[i,j]=path[path.length-1];
 if(i===0&&j===0){phase='done';pause=110;
  ops.reverse();
  return}
 let s=src[i][j];
 if(s==='='||s==='X'){if(s==='X')ops.push('substitute '+a[i-1]+'->'+b[j-1]);path.push([i-1,j-1])}
 else if(s==='D'){ops.push('delete '+a[i-1]);path.push([i-1,j])}
 else if(s==='I'){ops.push('insert '+b[j-1]);path.push([i,j-1])}
 else path.push([0,0])
}
function cellPos(i,j){return{x:ox+j*cell,y:oy+i*cell}}
function draw(){
 cx.fillStyle='#181818';cx.fillRect(0,0,cv.width,cv.height);
 cx.font='16px monospace';cx.fillStyle='#8cf';cx.textAlign='center';
 for(let j=0;j<=m;j++){let p=cellPos(0,j);cx.fillText(j===0?'':b[j-1],p.x,oy-30)}
 for(let i=0;i<=n;i++){let p=cellPos(i,0);cx.fillText(i===0?'':a[i-1],ox-40,p.y+6)}
 for(let i=0;i<=n;i++)for(let j=0;j<=m;j++){
  let p=cellPos(i,j);
  let filled=D[i][j]>=0;
  cx.fillStyle=filled?'#233':'#161616';
  cx.fillRect(p.x-cell/2+2,p.y-cell/2+2,cell-4,cell-4);
  if(filled){
   cx.fillStyle='#eee';cx.font='15px monospace';cx.fillText(D[i][j],p.x,p.y+5);
   cx.font='9px monospace';cx.fillStyle='#8a8';
   let s=src[i][j];let t=s==='D'?'del':s==='I'?'ins':s==='X'?'sub':'';
   cx.fillText(t,p.x,p.y+16)
  }
 }
 if(phase==='fill'&&oi<order.length){let[i,j]=order[oi];let p=cellPos(i,j);cx.strokeStyle='#ff0';cx.lineWidth=3;cx.strokeRect(p.x-cell/2+2,p.y-cell/2+2,cell-4,cell-4);cx.lineWidth=1}
 if(phase==='backtrace'||phase==='done'){
  cx.strokeStyle='#f66';cx.lineWidth=2;
  for(let k=0;k<path.length;k++){let p=cellPos(path[k][0],path[k][1]);cx.beginPath();cx.arc(p.x,p.y,cell/2-6,0,7);cx.stroke()}
 }
 cx.fillStyle='#fff';cx.font='16px monospace';cx.textAlign='left';
 cx.fillText('"'+a+'" -> "'+b+'"   Edit distance: '+(D[n][m]>=0?D[n][m]:'?'),20,25);
 if(phase==='done')cx.fillText('Ops: '+ops.join(', '),20,540);
 else if(phase==='backtrace')cx.fillText('Backtracking...',20,540)
}
function loop(){
 if(phase==='fill'){fillOne()}
 else if(phase==='backtrace'){if(pause<=0){backOne();pause=6}else pause--}
 else if(phase==='done'){pause--;if(pause<=0)reset()}
 draw();
 requestAnimationFrame(loop)
}
reset();loop();
</script></body></html>
Claude Haiku 4.5frontier referenceSTAT
Show code
<!DOCTYPE html><html><head><title>r68</title></head><body><canvas id="c"></canvas><script>
let c=document.getElementById('c'),x=c.getContext('2d');c.width=900;c.height=600;
let a="kitten",b="sitting",m=a.length+1,n=b.length+1;
let d=Array(m).fill(0).map(()=>Array(n).fill(0));
for(let i=0;i<m;i++)d[i][0]=i;for(let j=0;j<n;j++)d[0][j]=j;
let f=0,p=0,t=m*n,path=[],bt=0;
function draw(){
  x.fillStyle="#fff";x.fillRect(0,0,900,600);
  if(p<t-1){let i=Math.floor((p+1)/n);let j=(p+1)%n;if(i>0&&j>0){
    let s=d[i-1][j-1]+(a[i-1]!==b[j-1]?1:0),de=d[i-1][j]+1,in_=d[i][j-1]+1;
    d[i][j]=Math.min(s,de,in_);f++;p++;
  }}else if(bt<m+n){
    if(!path.length)path=[m-1,n-1];
    let i=path[path.length-2]||m-1,j=path[path.length-1]||n-1;
    if(i>0||j>0){
      if(i>0&&j>0&&d[i-1][j-1]<=d[i-1][j]&&d[i-1][j-1]<=d[i][j-1])path.push(i-1,j-1);
      else if(i>0&&d[i-1][j]<d[i][j-1])path.push(i-1,j);
      else if(j>0)path.push(i,j-1);
    }bt++;
  }
  let s=50;x.fillStyle="#000";x.font="11px mono";
  for(let i=0;i<m;i++)for(let j=0;j<n;j++){
    let pi=path.indexOf(i),pj=path.indexOf(j);
    x.fillStyle=(pi>=0&&pi+1<path.length&&path[pi+1]===j)?"#f00":"#eee";
    x.fillRect(j*s+50,i*s+50,s,s);x.strokeStyle="#999";x.strokeRect(j*s+50,i*s+50,s,s);
    x.fillStyle="#000";x.fillText(d[i][j],j*s+63,i*s+66);
  }
  x.fillText(a,50,m*s+120);x.fillText(b,150,m*s+120);
  x.fillText("Dist:"+d[m-1][n-1],50,550);
  requestAnimationFrame(draw);
}draw();
</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 —73.7 sOK
deepseek-r1:14b —48.8 sOK
mistral-small:24b —232.5 sOK
qwen3:14b —64.2 sOK
qwen3-coder:30b —40.9 sOK
llama3.1:8b —134.2 sOK
qwen3:8b ——harness
gemma4:26b ——harness
deepseek-r1:32b —135.8 sOK
qwq:32b —135.8 sOK
command-r:35b —150.8 sOK

Frontier reference — outside the blind field

These models answered the identical prompt outside the blind field. They are deliberately not scored and not part of the blind comparison — they are there so you can see where a frontier model lands on the same task.

Collected differently from the blind field: the local models run through a plain API harness, the frontier references through a context-free agent, one shot, no retries. Response times are therefore not comparable and are not shown. On two English tasks the reference answer came back in German — an artefact of that harness, flagged on the affected rounds.
Claude Opus 5frontier reference
Show code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Levenshtein DP Matrix</title>
<style>
html,body{margin:0;height:100%;background:#0d1117;color:#c9d1d9;font:14px ui-monospace,SFMono-Regular,Menlo,monospace;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px}
canvas{border-radius:12px;box-shadow:0 10px 40px #0008}
#out{min-height:96px;width:min(92vw,640px);background:#161b22;border:1px solid #30363d;border-radius:10px;padding:12px 16px;line-height:1.6;white-space:pre-wrap}
.k{color:#8b949e}
</style>
</head>
<body>
<canvas id="c"></canvas>
<div id="out"></div>
<script>
const words=["keyboard","elephant","computer","notebook","umbrella","mountain","sunlight","triangle","chocolate","telephone","butterfly","adventure","backspace","algorithm","developer","raspberry","blueprint","landscape","pineapple","waterfall"];
const cv=document.getElementById('c'),ctx=cv.getContext('2d'),out=document.getElementById('out');
const cs=42,ox=74,oy=100;
let A,B,n,m,d,dir,ts,order,fi,phase,path,ops,ci,cj,acc,wait,hold,prev,CW,CH;
function resize(){const dpr=window.devicePixelRatio||1;CW=ox+(m+1)*cs+26;CH=oy+(n+1)*cs+30;cv.style.width=CW+'px';cv.style.height=CH+'px';cv.width=CW*dpr;cv.height=CH*dpr;ctx.setTransform(dpr,0,0,dpr,0,0);}
function init(){
  A=words[Math.random()*words.length|0];do{B=words[Math.random()*words.length|0]}while(B===A);
  n=A.length;m=B.length;d=[];dir=[];ts=[];
  for(let i=0;i<=n;i++){d.push(new Array(m+1).fill(null));dir.push(new Array(m+1).fill(0));ts.push(new Array(m+1).fill(0));}
  order=[];for(let i=0;i<=n;i++)for(let j=0;j<=m;j++)order.push([i,j]);
  fi=0;phase=0;path=new Set();ops=[];ci=n;cj=m;acc=0;wait=0;resize();
}
function step(now){
  const p=order[fi++],i=p[0],j=p[1];
  if(!i&&!j){d[0][0]=0;dir[0][0]=0;}
  else if(!i){d[0][j]=j;dir[0][j]=1;}
  else if(!j){d[i][0]=i;dir[i][0]=2;}
  else{const c=A[i-1]===B[j-1]?0:1,sub=d[i-1][j-1]+c,ins=d[i][j-1]+1,del=d[i-1][j]+1;
    let best=sub,k=c?3:4;
    if(ins<best){best=ins;k=1}
    if(del<best){best=del;k=2}
    d[i][j]=best;dir[i][j]=k;}
  ts[i][j]=now;
}
function back(){
  path.add(ci+','+cj);
  if(!ci&&!cj){phase=2;ops.reverse();hold=performance.now();return}
  const k=dir[ci][cj];
  if(k===1){ops.push('insert  "'+B[cj-1]+'"  before position '+(ci+1));cj--}
  else if(k===2){ops.push('delete  "'+A[ci-1]+'"  at position '+ci);ci--}
  else{if(k===3)ops.push('replace "'+A[ci-1]+'" -> "'+B[cj-1]+'"  at position '+ci);ci--;cj--}
}
function arrow(k){return k===1?'←':k===2?'↑':'↖'}
function draw(now){
  ctx.fillStyle='#0d1117';ctx.fillRect(0,0,CW,CH);
  ctx.textAlign='center';ctx.textBaseline='middle';
  ctx.font='bold 22px ui-monospace,monospace';ctx.fillStyle='#e6edf3';
  ctx.fillText(A+'  →  '+B,CW/2,34);
  ctx.font='13px ui-monospace,monospace';ctx.fillStyle='#8b949e';
  ctx.fillText(phase===0?'filling dynamic programming matrix':phase===1?'walking the backtrace':'edit distance = '+d[n][m],CW/2,60);
  ctx.font='bold 19px ui-monospace,monospace';ctx.fillStyle='#7d8590';
  for(let j=1;j<=m;j++)ctx.fillText(B[j-1].toUpperCase(),ox+(j+.5)*cs,oy-24);
  for(let i=1;i<=n;i++)ctx.fillText(A[i-1].toUpperCase(),ox-26,oy+(i+.5)*cs);
  const cur=fi>0?order[fi-1]:null;
  for(let i=0;i<=n;i++)for(let j=0;j<=m;j++){
    if(d[i][j]===null)continue;
    const e=1-Math.pow(1-Math.min(1,(now-ts[i][j])/280),3),s=cs-5;
    const on=path.has(i+','+j),live=phase===0&&cur&&cur[0]===i&&cur[1]===j;
    ctx.save();ctx.translate(ox+(j+.5)*cs,oy+(i+.5)*cs);ctx.scale(.65+.35*e,.65+.35*e);ctx.globalAlpha=.15+.85*e;
    ctx.fillStyle=on?'#f0883e':live?'#1f6feb':'#161b22';
    ctx.strokeStyle=on?'#ffd7a8':live?'#79c0ff':'#30363d';ctx.lineWidth=on||live?2:1;
    ctx.beginPath();ctx.roundRect(-s/2,-s/2,s,s,7);ctx.fill();ctx.stroke();
    ctx.fillStyle=on?'#26160a':'#c9d1d9';ctx.font='bold 16px ui-monospace,monospace';
    ctx.fillText(d[i][j],1,2);
    const k=dir[i][j];
    if(k){ctx.font='11px ui-monospace,monospace';
      ctx.fillStyle=on?'#4a2c0d':k===4?'#3fb950':k===1?'#58a6ff':k===2?'#d29922':'#db6d28';
      ctx.fillText(arrow(k),-s/2+10,-s/2+10);}
    ctx.restore();
  }
  ctx.textAlign='left';ctx.font='12px ui-monospace,monospace';
  const leg=[['↖ match','#3fb950'],['↖ replace','#db6d28'],['← insert','#58a6ff'],['↑ delete','#d29922']];
  leg.forEach((L,i)=>{ctx.fillStyle=L[1];ctx.fillText(L[0],18+i*Math.min(120,(CW-40)/4),CH-14)});
}
function report(){
  if(phase===0){out.innerHTML='<span class="k">computing '+fi+' / '+order.length+' cells...</span>';return}
  const head='<span class="k">distance('+A+', '+B+') = </span><b>'+d[n][m]+'</b>\n';
  const body=ops.length?ops.map((o,i)=>(i+1)+'. '+o).join('\n'):'no operations needed';
  out.innerHTML=head+(phase===1?'<span class="k">backtracing...</span>\n':'')+body;
}
function loop(now){
  if(!prev)prev=now;const dt=Math.min(64,now-prev);prev=now;
  if(phase===0){acc+=dt;while(acc>=36&&fi<order.length){acc-=36;step(now)}
    if(fi>=order.length){wait+=dt;if(wait>650){phase=1;acc=0}}}
  else if(phase===1){acc+=dt;while(acc>=165&&phase===1){acc-=165;back()}}
  else if(now-hold>4200){init();}
  draw(now);report();requestAnimationFrame(loop);
}
init();requestAnimationFrame(loop);
addEventListener('resize',()=>resize());
</script>
</body>
</html>