Overview › Code › R87
Code · blind round

R87 · Gray-Scott reaction-diffusion

blind round 8/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 runs a Gray-Scott reaction-diffusion simulation on a grid of at least 120x120 cells and draws it to a <canvas> via ImageData: two chemicals diffuse at different rates and react, so a few seeded blobs grow into branching, coral-like patterns. Use a second buffer so a step never reads values it has already overwritten. Show the number of simulation steps. 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:14bERRBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html><head><title>Gray-Scott Simulation</title></head><body style="background:#000;margin:0;"><canvas id="c"></canvas><script>
    const c = document.getElementById('c');
    const ctx = c.getContext('2d');

    let S, G, A, B;
    let r, s, d_a, d_b, k;
    let bufferA, bufferB, nextA, nextB;
    let step = 0;

    function init(size) {
        S = size;
        G = size;
        c.width = c.height = S * 2; // Higher resolution for visual quality
        const scaleFactor = Math.floor(c.width / (S * 1.5)); // Scale down slightly to fit step counter
        c.style.width = `${Math.min(800, S*2)}px`;
        c.style.height = `${Math.min(600, S*2)}px`;

        bufferA = new Float32Array(S * S);
        bufferB = new Float32Array(S * S);
        nextA = new Float32Array(S * S);
        nextB = new Float32Array(S * S);

        // Parameters (Standard values for patterns)
        r = 0.055; // Reactant rate A consumption
        s = 1.0;   // Source strength B replacement
        d_a = 1.0; // Diffusion A
        d_b = 0.5; // Diffusion B
        k = 1.8;   // Reaction coefficient

        step = 0;

        // Seeding the initial state (Center area)
        for (let y = 0; y < S; y++) {
            for (let x = 0; x < S; x++) {
                const i = y * S + x;
                bufferA[i] = 1.0;
                bufferB[i] = 1.0;
            }
        }

        // Create a central 'seed' blob (B=0, A slightly higher)
        let startX = Math.floor(S * 0.3);
        let startY = Math.floor(S * 0.5);
        let radius = Math.floor(S * 0.15);

        for (let y = -radius; y <= radius; y++) {
            for (let x = -radius; x <= radius; x++) {
                const nx = startX + x;
                const ny = startY + y;

                if (nx >= 0 && nx < S && ny >= 0 && ny < S) {
                    const i = ny * S + nx;
                    bufferA[i] = 1.0; // High A
                    bufferB[i] = 0.0; // Low B
                }
            }
        }

        // Initialize the rendering background (black/dark)
        ctx.fillStyle = '#000';
        ctx.fillRect(0, 0, c.width, c.height);
    }

    function diffuse(p, buffer, nextBuffer, rate) {
        let sum = 0;
        for (let i = -1; i <= 1; i++) {
            for (let j = -1; j <= 1; j++) {
                if (i === 0 && j === 0) continue;
                const x = p[0] + i;
                const y = p[1] + j;

                if (x >= 0 && x < S && y >= 0 && y < S) {
                    sum += buffer[(y * S + x)];
                }
            }
        }
        return sum / 8.0;
    }

    function stepSimulation() {
        for (let y = 0; y < S; y++) {
            for (let x = 0; x < S; x++) {
                const i = y * S + x;

                // Calculate new A concentration (Diffusion and Reaction)
                let nextAVal = d_a * diffuse(p, bufferA, nextA, d_a);
                nextAVal = (bufferA[i] + 2.0 * d_a / 8.0 * (diffuse(p, bufferA, nextA, 0) - bufferA[i])) - r * bufferA[i] * bufferB[i] * bufferB[i];
                nextAVal = Math.max(0, Math.min(1, nextAVal));

                // Calculate new B concentration (Diffusion and Reaction)
                let nextBVal = d_b * diffuse(p, bufferB, nextB, d_b);
                nextBVal = (bufferB[i] + 2.0 * d_b / 8.0 * (diffuse(p, bufferB, nextB, 0) - bufferB[i])) + r * bufferA[i] * bufferB[i] * bufferB[i] - s * bufferB[i];
                nextBVal = Math.max(0, Math.min(1, nextBVal));

                // Store results in the 'next' buffers
                nextA[i] = nextAVal;
                nextB[i] = nextBVal;
            }
        }

        // Swap buffers (Next becomes Current)
        let temp = bufferA; bufferA = nextA; nextA = temp;
        temp = bufferB; bufferB = nextB; nextB = temp;

        step++;
    }
    
    function draw() {
        const imageData = ctx.getImageData(0, 0, c.width, c.height);
        const data = imageData.data;

        for (let y = 0; y < S; y++) {
            for (let x = 0; x < S; x++) {
                const i = y * S + x;
                
                // Normalize values to [0, 1] and scale them for color mapping.
                // A: Blue/Cyan component (e.g., higher A -> more blue)
                // B: Green component (e.g., higher B -> more green)
                // The combination creates the coral structure visualization.

                let a = bufferA[i]; 
                let b = bufferB[i]; 

                // Simple color mapping based on concentration ratio
                let rVal = Math.pow(Math.max(0, (1 - a)), 2); // Red intensity decreases with A
                let gVal = b * 2;                               // Green intensity proportional to B
                let bVal = a * 2;                               // Blue intensity proportional to A

                // Scale colors and apply to the ImageData array
                const dataIndex = (y * c.width + x) * 4;
                data[dataIndex]     = Math.floor(rVal * 255); // R
                data[dataIndex + 1] = Math.floor(gVal * 255); // G
                data[dataIndex + 2] = Math.floor(bVal * 255); // B
                data[dataIndex + 3] = 255;                        // A (Alpha)
            }
        }

        ctx.putImageData(imageData, 0, 0);
    }

    function loop() {
        stepSimulation();
        draw();
        requestAnimationFrame(loop);
    }

    init(160); // Use 160x160 grid for better detail while staying efficient
    loop();
</script></body></html>
```
mistral-small:24bERRBLANKMINIFIEDFORMAT
Show code
```html
<!DOCTYPE html>
<html><head><title>Gray-Scott Reaction-Diffusion</title></head><body onload="init()"> <canvas id="canvas"></canvas><script>function init(){const c=document.getElementById("canvas");c.width=600;c.height=600;const ctx=c.getContext("2dx");let w=c.width, h=c.height,size=128;const scale=w/size;ctx.fillStyle="white";ctx.fillRect(0,0,w,h);const dA=0.5,dB=0.3,f=0.04,k=0.06,dt=1;let U=new Float32Array(size*size),V=new Float32Array(size*size), Unew=new Float32Array(size*size), Vnew=new Float32Array(size*size);function Laplacian(U){let Utemp=new Float32Array(size*size);for(let i=1;i<size-1;++i)for(let j=1;j<size-1;++j)Utemp[i+size*j]=(U[(i+1)+size*(j)]+U[(i-1)+size*(j)]+U[i+size*(j+1)]+U[i+size*(j-1)]-4*U[i+size*j])/scale;Utemp[0]=Utemp[size-1]=Utemp[size*(size-1)]=Utemp[size-1]=Utemp[size*(size-1)+size-1]=Utemp[size*(size-1)]=Utemp[0+size*(size-1)]=Utemp[(size-2)+(size-1)*size]=Utemp[(size-2)+(size)*size];return Utemp}function step(){for(let i=0;i<size;++i){for(let j=0;j<size;++j){let idx=i*size+j;Unnew[idx]=U[idx]+dt*(dA*Laplacian(U)[idx]-U[idx]*V[idx]*V[idx]+f*(1-U[idx]));Vnew[idx]=V[idx]+dt*(dB*Laplacian(V)[idx]+U[idx]*V[idx]*V[idx]-(k+f)*V[idx]);}}let temp=U;U=Unnew;Unew=temp;temp=V;V=new Float32Array(size*size);for(let i=0;i<size*i<j<size;++i){V[i]=Vnew[i]}function draw(){ctx.putImageData(new ImageData(U.buffer,size,size),0,0)}draw();let stepCount=0;function simulate(){stepCount++;if(stepCount>15000)init();else{step();draw();requestAnimationFrame(simulate);}}simulate()}function randomSeed(size){for(let i=0;i<size*i<j<size;++i){U[i]=Math.random()<.3?1:0;V[i]=Math.random()<.2?1:0;}}randomSeed(size*size);</script></body></html>
```
deepseek-r1:14bOKFORMAT
Show code
```html
<!DOCTYPE html>
<html><body style="background:#000;margin:0;display:flex;justify-content:center;align-items:center;height:100vh">
<canvas id=c></canvas>
<div id=s>Steps: 0</div>
<script>
const c=document.getElementById('c'),s=document.getElementById('s');
const w=256,h=256;
const canvas=c.getContext('2d');

let buffer0=new ImageData(new Uint8ClampedArray(w*h*4),w,h);
let buffer1=new Uint8ClampedArray(w*h*4);

function initBuffers(){
  let ptr=0;
  for(let y=0;y<h;++y){
    const cy=Math.abs(y-h/2)/h*2;
    for(let x=0;x<w;++x){
      const cx=Math.abs(x-w/2)/w*2;
      buffer0.data[ptr++]=cx<.1?1:0;
      buffer0.data[ptr++]=cy<.1?1:0;
      buffer0.data[ptr++]=0;
      buffer0.data[ptr++]=(cx<.2||Math.random()<.05)*16;
    }
  }
}

let step=0,rateU=3e-4,diffU=8e-4,diffV=3e-4;
const updateGrids=function() {
  const data0=buffer0.data,data1=buffer1;
  for(let y=0;y<h;++y){
    for(let x=0;x<w;++x){
      const i=(y*w+x)*4;
      const u=data0[i],uv=data0[i+1];
      const vu=uv*uv; 
      data1[i]=(u - diffU*u + 2*vu/(1+uv))/(1+diffU);
      data1[i+1]=(uv - diffV*uv)/(1+diffV);
    }
  }
};

const drawGrid=function(buffer){
  canvas.putImageData(buffer,0,0);
}

function renderStep(){
  const data=buffer0.data;
  for(let y=0;y<h;++y){
    for(let x=0;x<w;++x){
      const i=(y*w+x)*4;
      const u=data[i],uv=data[i+1];
      let h1=256/(1+Math.exp(-u));
      let l=80*(u+uv)/4;
      if(uv<.1)h1=256/(1+Math.exp(-(u+.3)));
      data[i+3]=h1>l?h1-l:0;
    }
  }
}

function animate(){
  renderStep();
  canvas.putImageData(buffer0,0,0);
  s.textContent='Steps: '+step++;
  if(step%5!=0)requestAnimationFrame(animate);
  else{
    updateGrids();
    buffer0.data.set(buffer1);
    requestAnimationFrame(animate);
  }
}

initBuffers();
animate();

setInterval(()=>{
  const avgV=Array.from(buffer0.data).reduce((a,v,i)=>i%4==1?v+a:a,0)/buffer0.data.length;
  if(avgV<.1){
    initBuffers();
    step=0;
  }
},500);
</script></body></html>
```
qwen3.5:9bBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html><head><title>Gray-Scott Simulation</title></head><body style="background:#000;margin:0;"><canvas id="c"></canvas><script>
const N = 128;
let canvas, ctx;
let bufferA = new Float32Array(N * N); // A chemical concentration
let bufferB = new Float32Array(N * N); // B chemical concentration
let nextBufferA = new Float32Array(N * N);
let nextBufferB = new Float32Array(N * N);

// Parameters (Tuning for visible patterns)
const DA = 0.16;
const DB = 0.08;
const FEED_RATE = 0.055; // k
const KILL_RATE = 0.004; // m

let stepCount = 0;

function initialize() {
    canvas = document.getElementById('c');
    ctx = canvas.getContext('2d');
    canvas.width = N * 3;
    canvas.height = N * 3;
    
    // Seed the center with high B concentration (the catalyst)
    const center = Math.floor(N / 2);
    for (let i = 0; i < N * N; i++) {
        bufferA[i] = 1.0; // Start A at max
        bufferB[i] = 0.0; // Start B at zero
    }

    // Create a central "blob" of B (the seed)
    const radiusSq = Math.floor(N * N) / 80;
    for (let y = 0; y < N; y++) {
        for (let x = 0; x < N; x++) {
            const i = y * N + x;
            const distSq = (x - center)**2 + (y - center)**2;
            if (distSq < radiusSq) {
                bufferB[i] = Math.random() * 0.5 + 0.1; // Low initial B concentration
            }
        }
    }

    nextBufferA.fill(0);
    nextBufferB.fill(0);
    stepCount = 0;
    requestAnimationFrame(loop);
}

function diffLaplacian(buf, x, y) {
    let val = buf[(y - 1) * N + x] + buf[(y + 1) * N + x] + buf[y * N + (x - 1)] + buf[y * N + (x + 1)] - 4 * buf[y * N + x];
    return val;
}

function step() {
    // Swap buffers: current -> next, next -> current (Effectively swapping roles)
    [nextBufferA, bufferA] = [bufferA, nextBufferA];
    [nextBufferB, bufferB] = [bufferB, nextBufferB];

    for (let y = 1; y < N - 1; y++) {
        for (let x = 1; x < N - 1; x++) {
            const i = y * N + x;
            
            // Calculate Laplacian for A and B (using current values)
            const laplacianA = diffLaplacian(bufferA, x, y);
            const laplacianB = diffLaplacian(bufferB, x, y);

            // Reaction-Diffusion Equations:
            // d/dt A = DA * Laplacian(A) - A*B^2 + k*(1-A)
            let nextA = bufferA[i] + (DA * laplacianA - bufferA[i] * bufferB[i] * bufferB[i] + FEED_RATE * (1.0 - bufferA[i])) * 0.2;

            // d/dt B = DB * Laplacian(B) + A*B^2 - (k+m)*B
            let nextB = bufferB[i] + (DB * laplacianB + bufferA[i] * bufferB[i] * bufferB[i] - (FEED_RATE + KILL_RATE) * bufferB[i]) * 0.2;

            // Clamping and storing
            nextBufferA[i] = Math.max(0, Math.min(1, nextA));
            nextBufferB[i] = Math.max(0, Math.min(1, nextB));
        }
    }
    
    // Copy the calculated 'next' values back to the primary buffers for the next iteration
    for (let i = 0; i < N * N; i++) {
        bufferA[i] = nextBufferA[i];
        bufferB[i] = nextBufferB[i];
    }
}

function draw() {
    const imageData = ctx.getImageData(0, 0, N, N);
    const data = imageData.data;

    for (let y = 0; y < N; y++) {
        for (let x = 0; x < N; x++) {
            const i = y * N + x;
            // Normalize values for color mapping
            const a = bufferA[i];
            const b = bufferB[i];

            // Color map: A -> Red/Green, B -> Blue. Gradient mix for coral effect.
            let r = Math.floor(a * 255);
            let g = Math.floor(a * 100 + b * 150); // Green component depends on both
            let b_color = Math.floor(b * 255);

            const offset = (y * N + x) * 4;
            data[offset] = r;       // Red
            data[offset + 1] = g;   // Green
            data[offset + 2] = b_color; // Blue
            data[offset + 3] = 255; // Alpha (Opaque)
        }
    }

    ctx.putImageData(imageData, 0, 0);
}

function loop() {
    step();
    draw();
    document.querySelector('body').innerHTML = `<canvas id="c" width="${N*3}" height="${N*3}" style="display:block;">${""}</canvas><div style="color:#fff;font-family:monospace;margin-top:10px;">Steps: ${stepCount++}</div>`;
    requestAnimationFrame(loop);
}

initialize();
</script></body></html>
```
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.
llama3.1:8bSTATFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Gray-Scott Simulation</title>
<style>
  body {
    margin: 0;
    background-color: #f0f0f0;
  }
  canvas {
    border: 1px solid black;
  }
</style>
</head>
<body>

<script>
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);
canvas.width = 800;
canvas.height = 800;

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

var stepCount = 0;
var imageData = new Uint8ClampedArray(120 * 120 * 4);

for (var i = 0; i < 120 * 120; i++) {
  var x = Math.floor(i / 120) % 120;
  var y = Math.floor(i / 120);
  imageData[i * 4 + 3] = 255;
  if (Math.random() > 0.1) {
    imageData[i * 4] = 5;
    imageData[i * 4 + 1] = 10;
  }
}

function grayScott(u, v, d, f, k) {
  var du = u;
  var dv = v;
  for (var i = 0; i < 120; i++) {
    for (var j = 0; j < 120; j++) {
      var x = i * 120 + j;
      var a = imageData[x * 4];
      var b = imageData[x * 4 + 1];
      du -= d * (a * (b - u) - c * u);
      dv += d * (f * b * u - k * v * u - b);
    }
  }
  return [du, dv];
}

function draw() {
  var imageData2 = new Uint8ClampedArray(120 * 120 * 4);
  for (var i = 0; i < 120 * 120; i++) {
    var x = Math.floor(i / 120) % 120;
    var y = Math.floor(i / 120);
    var a = imageData[i * 4];
    var b = imageData[i * 4 + 1];
    if (a === 0 || b === 0) {
      imageData2[i * 4] = 0;
      imageData2[i * 4 + 1] = 0;
    } else {
      imageData2[i * 4] = a / Math.max(a, b);
      imageData2[i * 4 + 1] = b / Math.max(a, b);
    }
  }

  ctx.putImageData(new ImageData(imageData2, 120, 120), 0, 0);

  var du, dv;
  [du, dv] = grayScott(20, 10, 0.18, 0.08, 0.06);
  for (var i = 0; i < 120 * 120; i++) {
    var x = Math.floor(i / 120) % 120;
    var y = Math.floor(i / 120);
    imageData[i * 4 + 2] += du;
    imageData[i * 4 + 3] -= dv;
  }
  imageData[0 * 4] = 10;

  if (dv < -100 && stepCount === 0) {
    console.log(stepCount);
    location.reload();
  }

  requestAnimationFrame(draw);
}

draw();

var c = 20;
imageData[0 * 4 + 2] = 5;
for (var i = 1; i < 120 * 120; i++) {
  var x = Math.floor(i / 120) % 120;
  var y = Math.floor(i / 120);
  if (x === c && y === 0) {
    imageData[i * 4] = 5;
    imageData[i * 4 + 1] = 10;
  }
}

</script>
</body>
</html>
```
qwen3-coder:30bERRBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html><head><title>Gray-Scott Simulation</title></head><body style="background:#000;margin:0;"><canvas id="c"></canvas><script>
const c = document.getElementById('c');
const ctx = c.getContext('2d');

let W = 160; // Width
let H = 160; // Height (Choosing a power of two or easy number for buffer management)
let GRID_SIZE = W; 

c.width = W * 2; // Drawing resolution double the logical grid size for better display
c.height = H * 2;

const A = new Float32Array(W * H);
const B = new Float32Array(W * H);
let A_next = new Float32Array(W * H);
let B_next = new Float32Array(W * H);

// Simulation Parameters (Gray-Scott standard values)
const DA = 1.0; // Diffusion rate of A
const DB = 0.5; // Diffusion rate of B
const FEED = 0.055; // Feed rate
const KILL = 0.062; // Kill rate

let stepCount = 0;

function init() {
    // Initialize with random or seeded pattern (e.g., a central blob)
    for(let i=0; i < W*H; ++i) {
        A[i] = 1.0; // Initial A concentration
        B[i] = 0.0; // Initial B concentration
    }

    // Seed the pattern (center square blob, easier to control than pure random noise)
    let cx = Math.floor(W/3);
    let cy = Math.floor(H/3);
    for(let y=cy-10; y<cy+10; ++y) {
        for(let x=cx-10; x<cx+10; ++x) {
            if (x >= 0 && x < W && y >= 0 && y < H) {
                const i = y * W + x;
                A[i] = 0.8;
                B[i] = 0.9;
            }
        }
    }
}

function calculateLaplacian(arr, x, y, width) {
    let sum = 0;
    // Simple stencil: center - (neighbors * 1/4)
    sum += arr[(y-1)*width + x]; // Top
    sum += arr[(y+1)*width + x]; // Bottom
    sum += arr[y*width + (x-1)]; // Left
    sum += arr[y*width + (x+1)]; // Right
    return sum - 4 * arr[y * width + x];
}

function step() {
    // Swap buffers: A/B -> A_next/B_next
    [A, A_next] = [A_next, A];
    [B, B_next] = [B_next, B];
    
    // Use temporary storage for the new values before assignment
    for(let i=0; i < W*H; ++i) {
        A_next[i] = 0.0;
        B_next[i] = 0.0;
    }

    for (let y = 1; y < H - 1; y++) {
        for (let x = 1; x < W - 1; x++) {
            const i = y * W + x;
            
            // Calculate Laplacian for A and B at current position (using old values)
            let lapA = calculateLaplacian(A, x, y, W);
            let lapB = calculateLaplacian(B, x, y, W);

            const a = A[i];
            const b = B[i];

            // Gray-Scott Reaction Diffusion Equations:
            // 1. Diffusive terms (using previous step's values)
            // 2. Reaction term (-a*b^2 + k*(1-a)) is simplified/standardized below.
            
            const reaction = a * b * b; // The consumption rate
            
            // A_next = DA * Laplacian(A) - (a*b^2 + FEED*A)
            let nextA = DA * lapA - (reaction + FEED * a);

            // B_next = DB * Laplacian(B) + (a*b^2 - KILL*B)
            let nextB = DB * lapB + (reaction - KILL * b);


            A_next[i] = Math.min(1, Math.max(0, nextA)); // Clamp [0, 1]
            B_next[i] = Math.min(1, Math.max(0, nextB)); // Clamp [0, 1]
        }
    }

    // Copy the calculated next state back into the primary buffers for the next iteration
    for (let i = 0; i < W * H; ++i) {
        A[i] = A_next[i];
        B[i] = B_next[i];
    }

    stepCount++;
}

function draw() {
    const imageData = ctx.getImageData(0, 0, W * 2, H * 2);
    const data = imageData.data;
    let offset = 0;

    for (let y = 0; y < H; y++) {
        for (let x = 0; x < W; x++) {
            // Map normalized [0, 1] values to color components
            const a_val = A[y * W + x];
            const b_val = B[y * W + x];

            // Color mapping: (A, B) -> RGB. Example pattern: Blue/Cyan based on B, Green based on A.
            let r = Math.floor(a_val * 255);
            let g = Math.floor(b_val * 100 + a_val * 155);
            let b = Math.floor((1 - b_val) * 200);

            // Index in ImageData array (x, y, x+1, y, ...)
            data[offset++] = r;     // R
            data[offset++] = g;     // G
            data[offset++] = b;     // B
            data[offset++] = 255;   // A (Opacity)
        }
    }

    ctx.putImageData(imageData, 0, 0);
}

function animate() {
    step();
    draw();
    requestAnimationFrame(animate);
}

init();
animate();
</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.
command-r:35bERRBLANKMINIFIEDFORMAT
Show code
```html
<canvas id="c"></canvas>
<script>f=()=>{with(c={width:600,height:600,getContext:e=>({fillRect:(i,n,r,l)=>(s=[255*Math.random(),180*Math.random(),70*Math.random()],o=(t,a,u)=>[w=((t/=255)-.3)/F,.6/F*(a/=255-.1),(n=.9+e*.04-e**3)/(b*=.999+.001*e)],function({dx:g,dy:p},m){for(u=t=>o(s[t],l+=g,m+=p);s&&50> ++a;)for(d=[0,h.width];++x<d[1]&&++y<d[0];)e=4*y+3*d[1]+2*(w=x),u(b,o(b,i[w],l)),u(n,o(n,v[w],m));s=[i,v]=
[v,i]})},fillStyle:"#fff"}))t.clearRect(0,0,c.width,c.height),t.fillRect(...s=c.width/2-25,.9*c.height,.5*c.width+50,-1),e.fillImage(i,0,0),requestAnimationFrame(f))}with({buffer:a=[new Uint8ClampedArray(4*h.width*h.height)],dx:[1,0],dy:[0,1],F:.06})for(x=h.width;x--;)for(y=h.height;y--;)a[0][e=4*y+3*h.width+2*x]=o(n=.5,.5,-.06);f();setInterval(()=>{with({buffer:a=[new Uint8ClampedArray(b=a[1]),new Uint8ClampedArray(c=a[0])],dx:[1,0,1,-1],dy:[0,1,-1,0]})for(x=h.width;x--;)for(y=h.height;y--;){var [r,...l]=t=[4*(w=y)+3*h.width+2*(i=x)];([e]=c)[r]=-~e;n=e/255-.18;b[r]=o(n,c[(d=0)
],a[0][t[d]]);for(l=1;4>l++;){var [u,...m]=t=[r+dx[l],r+=dy[l]];([e]=c)[u]=o(b[u],c[u],a[0][t]);n=e/255-.18;if(.9> n&&.03< n)n=.46+.5*Math.random();else{var [g,...p]=t=[r+dx[l],r+=dy[l]];([e]=c)[u]=-~e;[e]=a[0][t];(b[u]=o(e,c[u],n))> .7&&1< ++s&&(s=0,c.fillStyle=`rgb(${[...c].map((_,d)=>a[0][t[d]])})`,c.fillRect(i+.5-1,w-.3,-2))}b[r]=-~e}e=.8*n+.76*s;for(l=1;4> l++;){var [u,...m]=t=[r+dx[l],r+=dy[l]];([e]=c)[u]=o(e,a[0][t],b[u])}}c.fillRect(...s="Steps: "+++s)}4E3,
document.body.appendChild(c),i=new ImageData(a[1],h.width,h.height))},25)},x=0,y=0,[w,i,n]=t,b=0,e=0,r=[],l=0,d=0;requestAnimationFrame(f)};
</script>
```
deepseek-r1:32bERRBLANKFORMAT
Show code
```html
<!DOCTYPE html><html><head><title>Gray-Scott Simulation</title></head><body>
<canvas id="c"></canvas>
<div id="steps">0</div>
<script>
const c=document.getElementById('c'),ctx=c.getContext('2d');
let w=128,h=64,step=0,F=0.025,k=0.06;
c.width=w*2;c.height=h*2;
let bufs=[new Float32Array(w*h),new Float32Array(w*h)];
let idx=0,buf=current=>bufs[current%2];
function init(){
  const u=1,v=0;step=0;
  for(let y=0;y<h;++y)
    for(let x=0;x<w;++x){
      let i=y*w+x;
      buf(0)[i]=u;
      buf(1)[i]=v;
    }
  for(let i=0;i<20;++i){
    const x=Math.random()*w,y=Math.random()*h,idx=~~y*w+~~x;
    buf(0)[idx]-=0.5;
  }
}
function compute(src,dst){
  const f=F,k=k,du=1-6*f+k, dv=1-6*k+f;
  for(let y=0;y<h;++y)
    for(let x=0;x<w;++x){
      let i=y*w+x;
      if(x===0||x===w-1||y===0||y===h-1){
        buf(dst)[i]=0;continue;
      }
      let sumU=0,sumV=0;
      for(let dy=-1;dy<=1;++dy)
        for(let dx=-1;dx<=1;++dx){
          const ny=(y+dy+h)%h,nx=(x+dx+w)%w;
          const j=ny*w+nx;
          sumU+=buf(src)[j];
          sumV+=buf(1)[j];
        }
      sumU=sumU/9	buf(src)[i]*(du) + f*(1-buf(src)[i]);
      sumV=sumV/9	buf(1)[i]*(dv) + buf(src)[i]*k;
      buf(dst)[i]=sumU;
      buf(1)[i]=sumV;
    }
}
function draw(){
  const d=ctx.createImageData(w,h);
  for(let y=0;y<h;++y)
    for(let x=0;x<w;++x){
      let i=y*w+x,j=i*4,u=buf(idx)[i];
      u=Math.max(0,Math.min(1,u));
      const v=buf(1)[i];
      d.data[j]=255*(u);
      d.data[j+1]=255*(u);
      d.data[j+2]=255*(u);
      d.data[j+3]=255;
    }
  ctx.putImageData(d,0,0);
}
function animate(){
  step++;
  if(step>1e4) init();
  compute(idx^1,idx);
  draw();
  document.getElementById('steps').textContent=step;
  requestAnimationFrame(animate);
}
init();animate();
</script></body></html>
```
No usable answer reached the harness (ERR). Counted as a did-not-finish.
Outside the Brain cluster — same task, same character budget, collected through their own tooling (response times not comparable)
Claude Opus 5frontier referenceOK
Show code
<!doctype html>
<html><head><meta charset="utf-8"><title>Gray-Scott reaction-diffusion</title>
<style>
html,body{margin:0;height:100%;background:#05070d;display:flex;align-items:center;
justify-content:center;overflow:hidden}
canvas{image-rendering:pixelated;width:min(96vh,96vw);height:min(96vh,96vw);
box-shadow:0 0 60px #0af3}
#hud{position:fixed;left:12px;top:11px;font:13px ui-monospace,monospace;color:#bfe0ff;
background:rgba(5,10,20,.6);padding:5px 9px;border-radius:5px}
</style></head><body>
<canvas id="c" width="150" height="150"></canvas><div id="hud">step 0</div>
<script>
const N=150,cv=document.getElementById('c'),g=cv.getContext('2d'),hud=document.getElementById('hud');
const img=g.createImageData(N,N);
const DA=1.0,DB=.5,F=.0545,K=.062,DT=1.0,PER_FRAME=14;
let a,b,a2,b2,steps=0;

function seed(){
  a=new Float32Array(N*N).fill(1);b=new Float32Array(N*N).fill(0);
  a2=new Float32Array(N*N);b2=new Float32Array(N*N);
  for(let s=0;s<7;s++){
    const cx=10+Math.random()*(N-20),cy=10+Math.random()*(N-20),r=4+Math.random()*5;
    for(let y=-r;y<=r;y++)for(let x=-r;x<=r;x++){
      if(x*x+y*y>r*r)continue;
      const i=((cy+y|0)*N)+(cx+x|0);
      if(i>=0&&i<N*N){a[i]=.5;b[i]=.25+Math.random()*.25}
    }
  }
  steps=0;
}
seed();

function step(){
  for(let y=0;y<N;y++){
    const yu=(y-1+N)%N,yd=(y+1)%N;
    for(let x=0;x<N;x++){
      const xl=(x-1+N)%N,xr=(x+1)%N,i=y*N+x;
      const av=a[i],bv=b[i];
      const la=(a[y*N+xl]+a[y*N+xr]+a[yu*N+x]+a[yd*N+x])*.2
              +(a[yu*N+xl]+a[yu*N+xr]+a[yd*N+xl]+a[yd*N+xr])*.05-av;
      const lb=(b[y*N+xl]+b[y*N+xr]+b[yu*N+x]+b[yd*N+x])*.2
              +(b[yu*N+xl]+b[yu*N+xr]+b[yd*N+xl]+b[yd*N+xr])*.05-bv;
      const abb=av*bv*bv;
      let na=av+(DA*la-abb+F*(1-av))*DT;
      let nb=bv+(DB*lb+abb-(K+F)*bv)*DT;
      a2[i]=na<0?0:na>1?1:na;
      b2[i]=nb<0?0:nb>1?1:nb;
    }
  }
  let t=a;a=a2;a2=t;t=b;b=b2;b2=t;
  steps++;
}

function draw(){
  const d=img.data;
  for(let i=0;i<N*N;i++){
    const v=a[i]-b[i], c=v<0?0:v>1?1:v;
    d[i*4]  =18+c*40;
    d[i*4+1]=30+(1-c)*170;
    d[i*4+2]=60+c*180;
    d[i*4+3]=255;
  }
  g.putImageData(img,0,0);
}

function frame(){
  for(let s=0;s<PER_FRAME;s++)step();
  draw();
  hud.textContent='step '+steps+'  ·  grid '+N+'×'+N;
  if(steps>9000)seed();
  requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
</script></body></html>
GPT-5.5 (Codex)frontier referenceOKMINIFIED
Show code
<!doctype html><html><head><meta charset=utf-8><title>Gray-Scott</title><style>html,body{margin:0;height:100%;background:#05070a;color:#d8f3ff;font:16px system-ui;overflow:hidden}canvas{width:100vw;height:100vh;image-rendering:pixelated;display:block}#s{position:fixed;left:14px;top:10px;text-shadow:0 1px 4px #000}</style></head><body><canvas id=c></canvas><div id=s></div><script>
let n=144,m=n*n,a,b,A,B,img,d,step,run=0,done=0,cv=c,ctx=cv.getContext('2d'),lab=s;
function R(){cv.width=n;cv.height=n;img=ctx.createImageData(n,n);d=img.data;A=new Float32Array(m);B=new Float32Array(m);a=new Float32Array(m);b=new Float32Array(m);for(let i=0;i<m;i++)A[i]=a[i]=1,B[i]=b[i]=0;for(let k=0;k<9;k++){let x=20+Math.random()*(n-40)|0,y=20+Math.random()*(n-40)|0,r=4+Math.random()*8|0;for(let j=-r;j<=r;j++)for(let i=-r;i<=r;i++)if(i*i+j*j<r*r){let p=(y+j)*n+x+i;B[p]=b[p]=.8+Math.random()*.2;A[p]=a[p]=.1}}step=0;run++;done=0}
function tick(){
for(let q=0;q<6;q++){for(let y=1;y<n-1;y++)for(let x=1;x<n-1;x++){let i=y*n+x,u=A[i],v=B[i],la=A[i-1]+A[i+1]+A[i-n]+A[i+n]+.05*(A[i-n-1]+A[i-n+1]+A[i+n-1]+A[i+n+1])-4.2*u,lb=B[i-1]+B[i+1]+B[i-n]+B[i+n]+.05*(B[i-n-1]+B[i-n+1]+B[i+n-1]+B[i+n+1])-4.2*v,r=u*v*v,f=.026+.01*Math.sin(run),k=.055+.006*Math.random();a[i]=u+(1*la-r+f*(1-u));b[i]=v+(.5*lb+r-(k+f)*v);if(a[i]<0)a[i]=0;if(a[i]>1)a[i]=1;if(b[i]<0)b[i]=0;if(b[i]>1)b[i]=1}let t=A;A=a;a=t;t=B;B=b;b=t;step++}
let live=0;for(let i=0;i<m;i++){let v=B[i],p=i*4,g=(v*280)|0;if(v>.04)live++;d[p]=g*.25;d[p+1]=g*.75+30;d[p+2]=g+40;d[p+3]=255}ctx.putImageData(img,0,0);lab.textContent="steps "+step;if(step>6500||step>1200&&live<80)R();requestAnimationFrame(tick)}
R();tick();
</script></body></html>
Claude Sonnet 5frontier referenceOK
Show code
<!DOCTYPE html><html><head><meta charset="utf8"><title>Gray-Scott</title><style>
body{margin:0;background:#000;overflow:hidden}canvas{display:block;margin:0 auto}
#i{position:fixed;top:8px;left:8px;color:#9f9;font:14px monospace}
</style></head><body><canvas id="c"></canvas><div id="i"></div><script>
const N=140,cv=document.getElementById('c'),ctx=cv.getContext('2d');
cv.width=560;cv.height=560;
const img=ctx.createImageData(N,N);
let A,B,A2,B2,steps=0,dA=1,dB=0.5,f,k;
function idx(x,y){x=(x+N)%N;y=(y+N)%N;return y*N+x}
function init(){
  A=new Float32Array(N*N).fill(1);B=new Float32Array(N*N).fill(0);
  A2=new Float32Array(N*N);B2=new Float32Array(N*N);
  f=0.03+Math.random()*0.03; k=0.055+Math.random()*0.015;
  const blobs=4+Math.floor(Math.random()*4);
  for(let b=0;b<blobs;b++){
    const cx=Math.random()*N,cy=Math.random()*N,r=4+Math.random()*4;
    for(let y=-r;y<r;y++)for(let x=-r;x<r;x++){
      if(x*x+y*y<r*r){
        const i=idx(Math.floor(cx+x),Math.floor(cy+y));
        A[i]=0.5+Math.random()*0.1; B[i]=0.25+Math.random()*0.1;
      }
    }
  }
  steps=0;
}
init();
function step(){
  for(let y=0;y<N;y++){
    for(let x=0;x<N;x++){
      const i=idx(x,y);
      const lapA=A[idx(x-1,y)]+A[idx(x+1,y)]+A[idx(x,y-1)]+A[idx(x,y+1)]+
        0.05*(A[idx(x-1,y-1)]+A[idx(x+1,y-1)]+A[idx(x-1,y+1)]+A[idx(x+1,y+1)])-4.2*A[i];
      const lapB=B[idx(x-1,y)]+B[idx(x+1,y)]+B[idx(x,y-1)]+B[idx(x,y+1)]+
        0.05*(B[idx(x-1,y-1)]+B[idx(x+1,y-1)]+B[idx(x-1,y+1)]+B[idx(x+1,y+1)])-4.2*B[i];
      const a=A[i],b=B[i],reac=a*b*b;
      let na=a+(dA*lapA-reac+f*(1-a));
      let nb=b+(dB*lapB+reac-(k+f)*b);
      A2[i]=Math.min(1,Math.max(0,na));
      B2[i]=Math.min(1,Math.max(0,nb));
    }
  }
  [A,A2]=[A2,A];[B,B2]=[B2,B];
  steps++;
}
function render(){
  const d=img.data;
  for(let i=0;i<N*N;i++){
    const v=Math.max(0,Math.min(1,A[i]-B[i]));
    const c=Math.floor(v*255);
    const g=Math.floor((1-v)*B[i]*400+40);
    d[i*4]=Math.min(255,c*0.3);
    d[i*4+1]=Math.min(255,c*0.9+30);
    d[i*4+2]=Math.min(255,c*1.1+g);
    d[i*4+3]=255;
  }
  const tmp=document.createElement('canvas');
  tmp.width=N;tmp.height=N;
  tmp.getContext('2d').putImageData(img,0,0);
  ctx.imageSmoothingEnabled=true;
  ctx.drawImage(tmp,0,0,cv.width,cv.height);
  ctx.fillStyle='rgba(0,0,0,0.5)';
  ctx.fillRect(0,0,220,26);
  ctx.fillStyle='#9f9';
  ctx.font='14px monospace';
  ctx.fillText('steps: '+steps,8,18);
}
function loop(){
  for(let s=0;s<10;s++)step();
  render();
  if(steps>6000+Math.random()*2000) init();
  requestAnimationFrame(loop);
}
loop();
</script></body></html>
Claude Fable 5frontier referenceOK
Show code
<!DOCTYPE html><html><head><meta charset="utf-8"><title>Gray-Scott Reaction-Diffusion</title><style>html,body{margin:0;height:100%;overflow:hidden;background:#000}canvas{display:block;width:100vw;height:100vh;image-rendering:auto}#h{position:fixed;top:10px;left:10px;color:#fff;font:14px monospace;background:rgba(0,0,0,.5);padding:6px 10px;border-radius:6px}</style></head><body><canvas id="c"></canvas><div id="h"></div><script>
const N=160,cv=document.getElementById("c"),g=cv.getContext("2d"),hud=document.getElementById("h");
cv.width=N;cv.height=N;
const A=new Float32Array(N*N),B=new Float32Array(N*N),A2=new Float32Array(N*N),B2=new Float32Array(N*N);
const img=g.createImageData(N,N),px=img.data;
const presets=[[.0367,.0649],[.055,.062],[.029,.057],[.026,.051],[.022,.051],[.018,.051],[.03,.0565]];
let f,k,steps=0;
function reset(){
const p=presets[Math.random()*presets.length|0];
f=p[0]+(Math.random()-.5)*.002;k=p[1]+(Math.random()-.5)*.001;
A.fill(1);B.fill(0);steps=0;
const nb=5+(Math.random()*6|0);
for(let s=0;s<nb;s++){
const cx=8+Math.random()*(N-16)|0,cy=8+Math.random()*(N-16)|0,r=2+Math.random()*4;
for(let y=-6;y<=6;y++)for(let x=-6;x<=6;x++){
if(x*x+y*y<=r*r){const i=((cy+y)&(N-1))*N+((cx+x)&(N-1));B[i]=1;A[i]=.4}}}}
function step(){
const dA=1,dB=.5;
for(let y=0;y<N;y++){
const ym=((y-1)&(N-1))*N,yp=((y+1)&(N-1))*N,y0=y*N;
for(let x=0;x<N;x++){
const xm=(x-1)&(N-1),xp=(x+1)&(N-1);
const i=y0+x,a=A[i],b=B[i];
const la=(A[y0+xm]+A[y0+xp]+A[ym+x]+A[yp+x])*.2+(A[ym+xm]+A[ym+xp]+A[yp+xm]+A[yp+xp])*.05-a;
const lb=(B[y0+xm]+B[y0+xp]+B[ym+x]+B[yp+x])*.2+(B[ym+xm]+B[ym+xp]+B[yp+xm]+B[yp+xp])*.05-b;
const abb=a*b*b;
A2[i]=a+(dA*la-abb+f*(1-a));
B2[i]=b+(dB*lb+abb-(k+f)*b);
}}
A.set(A2);B.set(B2);steps++;
}
function draw(){
for(let i=0;i<N*N;i++){
const v=Math.min(1,B[i]*3.2),w=Math.max(0,Math.min(1,(A[i]-B[i])));
const j=i*4;
px[j]=12+v*243|0;px[j+1]=16+v*160+w*20|0;px[j+2]=48+v*60+w*40|0;px[j+3]=255;
}
g.putImageData(img,0,0);
}
reset();
function frame(){
requestAnimationFrame(frame);
for(let s=0;s<10;s++)step();
draw();
hud.textContent="Gray-Scott "+N+"x"+N+"  steps: "+steps+"  f="+f.toFixed(4)+" k="+k.toFixed(4);
if(steps>=9000)reset();
}
requestAnimationFrame(frame);
</script></body></html>
Claude Haiku 4.5frontier referenceOKMINIFIED
Show code
<!DOCTYPE html><html><head><meta charset="utf-8"><style>body{margin:0;background:#000;overflow:hidden}#c{display:block}#i{position:absolute;top:5px;left:5px;color:#0f0;font-family:monospace;font-size:12px}</style></head><body><canvas id="c"></canvas><div id="i"></div><script>const c=document.getElementById('c'),ctx=c.getContext('2d'),i=document.getElementById('i');c.width=600;c.height=600;const S=120,sz=S*S,du=0.16,dv=0.08,f=0.035,k=0.065;let u=new Float32Array(sz),v=new Float32Array(sz),nu=new Float32Array(sz),nv=new Float32Array(sz);u.fill(1);v.fill(0);for(let j=40;j<80;j++){for(let l=40;l<80;l++){u[j*S+l]=0.5;v[j*S+l]=0.25}}let st=0;function dr(){for(let y=1;y<S-1;y++){for(let x=1;x<S-1;x++){let j=y*S+x;let la=(u[j-1]+u[j+1]+u[j-S]+u[j+S]-4*u[j]);let lb=(v[j-1]+v[j+1]+v[j-S]+v[j+S]-4*v[j]);nu[j]=u[j]+du*la-u[j]*v[j]*v[j]+f*(1-u[j]);nv[j]=v[j]+dv*lb+u[j]*v[j]*v[j]-(k+f)*v[j]}}[u,v]=[nu,nv];let id=ctx.createImageData(S,S),d=id.data;for(let j=0;j<sz;j++){let c=Math.floor(v[j]*255);d[j*4+0]=c;d[j*4+1]=0;d[j*4+2]=255-c;d[j*4+3]=255}ctx.putImageData(id,0,0);ctx.scale(600/S,600/S);ctx.putImageData(id,0,0);ctx.scale(S/600,S/600);st++;i.textContent=`Steps: ${st}`}setInterval(dr,50);</script></body></html>
Results at a glance— every model in this round with score, response time and status.

Who wrote what

ModelBlind scoreLatencyStatus
qwen3:14b —28.4 sOK
mistral-small:24b —183.1 sOK
deepseek-r1:14b —98.5 sOK
qwen3.5:9b —26.5 sOK
gemma4:26b ——harness
llama3.1:8b —101.2 sOK
qwen3-coder:30b —25.4 sOK
qwen3:8b ——harness
command-r:35b —134.2 sOK
deepseek-r1:32b —292.1 sOK
qwq:32b ——DNF