Below are training examples: small colored grids that turn into other grids by some consistent rule. Study them, then apply what you learned to the test grid.
<p class="hint">Each example turns an input grid into an output grid by the <b>same</b> hidden rule. Study both examples, click cells on the answer grid to cycle their color, and reproduce the rule on the test grid.</p>
<div class="examples" id="examples"></div>
<div class="test-wrap">
<div class="test-col">
<div class="label">Test input</div>
<div class="grid" id="test-input"></div>
</div>
<div class="arrow">→</div>
<div class="test-col">
<div class="label">Your answer (click cells)</div>
<div class="grid" id="test-answer"></div>
</div>
</div>
<div class="status" id="status">Click the cells to change their color, then check.</div>
<div class="btns">
<button id="check" type="button">Check answer</button>
<button id="reveal" type="button">Reveal solution</button>
<button id="reset" type="button" class="ghost">Reset</button>
</div>
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; color: #222; margin: 0; }
.hint { font-size: .9rem; color: #444; margin: 0 0 .7rem; line-height: 1.45; }
.examples { display: flex; gap: 1.2rem; flex-wrap: wrap; margin-bottom: .9rem; }
.example { display: flex; align-items: center; gap: .5rem; }
.label { font-size: .75rem; font-weight: 700; color: #555; text-transform: uppercase;
letter-spacing: .03em; margin-bottom: .3rem; }
.grid { display: grid; grid-template-columns: repeat(3, 28px); gap: 2px;
background: #cdd9e3; padding: 2px; border-radius: 6px; }
.grid.big { grid-template-columns: repeat(3, 36px); }
.cell { width: 28px; height: 28px; border-radius: 3px; background: #eef1f4; cursor: default; }
.grid.big .cell { width: 36px; height: 36px; cursor: pointer; transition: transform .08s; }
.grid.big .cell:hover { transform: scale(1.06); }
.arrow { font-size: 1.3rem; color: #1d3557; margin: 0 .4rem; align-self: center; }
.test-wrap { display: flex; align-items: flex-end; gap: .6rem; flex-wrap: wrap; margin-bottom: .6rem; }
.test-col { display: flex; flex-direction: column; }
.status { font-size: 1rem; font-weight: 600; margin: .5rem 0; min-height: 1.4em; }
.status.ok { color: #0a7d33; }
.status.bad { color: #c92f3c; }
.btns { display: flex; gap: .5rem; flex-wrap: wrap; }
button { font: 600 14px system-ui, sans-serif; padding: .45rem .9rem; border: 1px solid #1d3557;
background: #1d3557; color: #fff; border-radius: 8px; cursor: pointer; }
button.ghost { background: #fff; color: #1d3557; }
const fmt = (s, v) => s.replace(/%(\w+)%/g, (_, k) => String(v[k] ?? ''));
// A miniature ARC-AGI-style task: infer a grid transformation rule from a couple of
const N = 3;
// 0 = background (light gray); 1..4 = distinct colors, cycled by clicking a cell.
const PALETTE = ['#eef1f4', '#e63946', '#2a9d8f', '#e9c46a', '#3d5a80'];
// Two training pairs (input grid -> output grid) that share one common rule.
const EX1_IN = [[0,0,1],[0,1,0],[1,0,0]];
const EX1_OUT = [[1,0,0],[0,1,0],[0,0,1]];
const EX2_IN = [[2,0,0],[0,0,0],[0,0,3]];
const EX2_OUT = [[0,0,2],[0,0,0],[3,0,0]];
// The test input the player must transform by hand, applying the inferred rule.
const TEST_IN = [[0,4,0],[4,0,4],[0,0,4]];
const SOLUTION = [[0,4,0],[4,0,4],[4,0,0]]; // the rule is a left-right mirror of the grid; SOLUTION is precomputed for checking
// The player's current answer grid, mutated by clicking cells.
let answer = TEST_IN.map(row => row.slice());
function makeGrid(container, grid, opts){
container.innerHTML = '';
container.classList.toggle('big', !!(opts && opts.big));
grid.forEach((row, r) => row.forEach((v, c) => {
const d = document.createElement('div');
d.className = 'cell';
d.style.background = PALETTE[v] || PALETTE[0];
if (opts && opts.clickable) {
d.addEventListener('click', () => {
answer[r][c] = (answer[r][c] + 1) % PALETTE.length;
renderAnswer();
setStatus('Click the cells to change their color, then check.', '');
});
}
container.appendChild(d);
}));
}
function renderExamples(){
const wrap = document.getElementById('examples');
wrap.innerHTML = '';
[[EX1_IN, EX1_OUT], [EX2_IN, EX2_OUT]].forEach(([inG, outG], i) => {
const ex = document.createElement('div');
ex.className = 'example';
const colIn = document.createElement('div');
const labIn = document.createElement('div');
labIn.className = 'label';
labIn.textContent = fmt('Example %n%', { n: i + 1 });
const gIn = document.createElement('div');
gIn.className = 'grid';
colIn.appendChild(labIn); colIn.appendChild(gIn);
makeGrid(gIn, inG, {});
const arrow = document.createElement('div');
arrow.className = 'arrow';
arrow.textContent = '→';
const colOut = document.createElement('div');
const labOut = document.createElement('div');
labOut.className = 'label';
labOut.textContent = ' ';
const gOut = document.createElement('div');
gOut.className = 'grid';
colOut.appendChild(labOut); colOut.appendChild(gOut);
makeGrid(gOut, outG, {});
ex.appendChild(colIn); ex.appendChild(arrow); ex.appendChild(colOut);
wrap.appendChild(ex);
});
}
function renderTestInput(){
makeGrid(document.getElementById('test-input'), TEST_IN, { big: true });
}
function renderAnswer(){
makeGrid(document.getElementById('test-answer'), answer, { big: true, clickable: true });
}
function setStatus(t, cls){
const s = document.getElementById('status');
s.textContent = t;
s.className = 'status ' + cls;
}
// The answer is correct iff it matches SOLUTION cell for cell.
function isCorrect(){
for (let r = 0; r < N; r++) for (let c = 0; c < N; c++)
if (answer[r][c] !== SOLUTION[r][c]) return false;
return true;
}
document.getElementById('check').addEventListener('click', () => {
if (isCorrect()) setStatus('✓ Correct — you inferred the rule from just two examples!', 'ok');
else setStatus('✗ Not quite. Compare inputs and outputs again — what moved, and where?', 'bad');
});
document.getElementById('reveal').addEventListener('click', () => {
answer = SOLUTION.map(row => row.slice());
renderAnswer();
setStatus('This is the correct output for the hidden rule.', 'ok');
console.log('Hidden rule:', 'mirror the grid left-to-right');
});
document.getElementById('reset').addEventListener('click', () => {
answer = TEST_IN.map(row => row.slice());
renderAnswer();
setStatus('Click the cells to change their color, then check.', '');
});
renderExamples();
renderTestInput();
renderAnswer();
<p class="hint">Each example turns an input grid into an output grid by the <b>same</b> hidden rule. Study both examples, click cells on the answer grid to cycle their color, and reproduce the rule on the test grid.</p>
<div class="examples" id="examples"></div>
<div class="test-wrap">
<div class="test-col">
<div class="label">Test input</div>
<div class="grid" id="test-input"></div>
</div>
<div class="arrow">→</div>
<div class="test-col">
<div class="label">Your answer (click cells)</div>
<div class="grid" id="test-answer"></div>
</div>
</div>
<div class="status" id="status">Click the cells to change their color, then check.</div>
<div class="btns">
<button id="check" type="button">Check answer</button>
<button id="reveal" type="button">Reveal solution</button>
<button id="reset" type="button" class="ghost">Reset</button>
</div>
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; color: #222; margin: 0; }
.hint { font-size: .9rem; color: #444; margin: 0 0 .7rem; line-height: 1.45; }
.examples { display: flex; gap: 1.2rem; flex-wrap: wrap; margin-bottom: .9rem; }
.example { display: flex; align-items: center; gap: .5rem; }
.label { font-size: .75rem; font-weight: 700; color: #555; text-transform: uppercase;
letter-spacing: .03em; margin-bottom: .3rem; }
.grid { display: grid; grid-template-columns: repeat(3, 28px); gap: 2px;
background: #cdd9e3; padding: 2px; border-radius: 6px; }
.grid.big { grid-template-columns: repeat(3, 36px); }
.cell { width: 28px; height: 28px; border-radius: 3px; background: #eef1f4; cursor: default; }
.grid.big .cell { width: 36px; height: 36px; cursor: pointer; transition: transform .08s; }
.grid.big .cell:hover { transform: scale(1.06); }
.arrow { font-size: 1.3rem; color: #1d3557; margin: 0 .4rem; align-self: center; }
.test-wrap { display: flex; align-items: flex-end; gap: .6rem; flex-wrap: wrap; margin-bottom: .6rem; }
.test-col { display: flex; flex-direction: column; }
.status { font-size: 1rem; font-weight: 600; margin: .5rem 0; min-height: 1.4em; }
.status.ok { color: #0a7d33; }
.status.bad { color: #c92f3c; }
.btns { display: flex; gap: .5rem; flex-wrap: wrap; }
button { font: 600 14px system-ui, sans-serif; padding: .45rem .9rem; border: 1px solid #1d3557;
background: #1d3557; color: #fff; border-radius: 8px; cursor: pointer; }
button.ghost { background: #fff; color: #1d3557; }
const fmt = (s, v) => s.replace(/%(\w+)%/g, (_, k) => String(v[k] ?? ''));
// A miniature ARC-AGI-style task: infer a grid transformation rule from a couple of
const N = 3;
// 0 = background (light gray); 1..4 = distinct colors, cycled by clicking a cell.
const PALETTE = ['#eef1f4', '#e63946', '#2a9d8f', '#e9c46a', '#3d5a80'];
// Two training pairs (input grid -> output grid) that share one common rule.
const EX1_IN = [[0,0,1],[0,1,0],[1,0,0]];
const EX1_OUT = [[1,0,0],[0,1,0],[0,0,1]];
const EX2_IN = [[2,0,0],[0,0,0],[0,0,3]];
const EX2_OUT = [[0,0,2],[0,0,0],[3,0,0]];
// The test input the player must transform by hand, applying the inferred rule.
const TEST_IN = [[0,4,0],[4,0,4],[0,0,4]];
const SOLUTION = [[0,4,0],[4,0,4],[4,0,0]]; // the rule is a left-right mirror of the grid; SOLUTION is precomputed for checking
// The player's current answer grid, mutated by clicking cells.
let answer = TEST_IN.map(row => row.slice());
function makeGrid(container, grid, opts){
container.innerHTML = '';
container.classList.toggle('big', !!(opts && opts.big));
grid.forEach((row, r) => row.forEach((v, c) => {
const d = document.createElement('div');
d.className = 'cell';
d.style.background = PALETTE[v] || PALETTE[0];
if (opts && opts.clickable) {
d.addEventListener('click', () => {
answer[r][c] = (answer[r][c] + 1) % PALETTE.length;
renderAnswer();
setStatus('Click the cells to change their color, then check.', '');
});
}
container.appendChild(d);
}));
}
function renderExamples(){
const wrap = document.getElementById('examples');
wrap.innerHTML = '';
[[EX1_IN, EX1_OUT], [EX2_IN, EX2_OUT]].forEach(([inG, outG], i) => {
const ex = document.createElement('div');
ex.className = 'example';
const colIn = document.createElement('div');
const labIn = document.createElement('div');
labIn.className = 'label';
labIn.textContent = fmt('Example %n%', { n: i + 1 });
const gIn = document.createElement('div');
gIn.className = 'grid';
colIn.appendChild(labIn); colIn.appendChild(gIn);
makeGrid(gIn, inG, {});
const arrow = document.createElement('div');
arrow.className = 'arrow';
arrow.textContent = '→';
const colOut = document.createElement('div');
const labOut = document.createElement('div');
labOut.className = 'label';
labOut.textContent = ' ';
const gOut = document.createElement('div');
gOut.className = 'grid';
colOut.appendChild(labOut); colOut.appendChild(gOut);
makeGrid(gOut, outG, {});
ex.appendChild(colIn); ex.appendChild(arrow); ex.appendChild(colOut);
wrap.appendChild(ex);
});
}
function renderTestInput(){
makeGrid(document.getElementById('test-input'), TEST_IN, { big: true });
}
function renderAnswer(){
makeGrid(document.getElementById('test-answer'), answer, { big: true, clickable: true });
}
function setStatus(t, cls){
const s = document.getElementById('status');
s.textContent = t;
s.className = 'status ' + cls;
}
// The answer is correct iff it matches SOLUTION cell for cell.
function isCorrect(){
for (let r = 0; r < N; r++) for (let c = 0; c < N; c++)
if (answer[r][c] !== SOLUTION[r][c]) return false;
return true;
}
document.getElementById('check').addEventListener('click', () => {
if (isCorrect()) setStatus('✓ Correct — you inferred the rule from just two examples!', 'ok');
else setStatus('✗ Not quite. Compare inputs and outputs again — what moved, and where?', 'bad');
});
document.getElementById('reveal').addEventListener('click', () => {
answer = SOLUTION.map(row => row.slice());
renderAnswer();
setStatus('This is the correct output for the hidden rule.', 'ok');
console.log('Hidden rule:', 'mirror the grid left-to-right');
});
document.getElementById('reset').addEventListener('click', () => {
answer = TEST_IN.map(row => row.slice());
renderAnswer();
setStatus('Click the cells to change their color, then check.', '');
});
renderExamples();
renderTestInput();
renderAnswer();
Notice what you just did: nobody told you the rule in words. You looked at two or three examples and induced it — the same jump from "a few instances" to "a general procedure" that every ARC-AGI task demands, and that current AI systems still make unreliably.
Comments
Loading comments...