ARC Prize 2026
$2M pool, hardest ML comp. Portfolio gold even without winning.
The world's most prestigious AI/AGI competition. ARC-AGI tests whether AI can reason the way humans do on abstract visual tasks. Winning requires genuine AI break…
Connected to the competition feed. Verify dates, eligibility and prizes on the official page.
$2M pool, hardest ML comp. Portfolio gold even without winning.
Subscribe once — every open competition's deadline shows up in your native calendar and auto-updates daily as new ones open and old ones close. No account needed.
Outlook or another app: copy the feed URL, then add a calendar from URL.
The world's most prestigious AI/AGI competition. ARC-AGI tests whether AI can reason the way humans do on abstract visual tasks. Winning requires genuine AI breakthroughs — not just engineering tricks.
| Date | Event |
|---|---|
| Mar 25 2026 | Competition opens |
| Jun 30 2026 | ARC-AGI-3 Milestone 1 |
| Sep 30 2026 | ARC-AGI-3 Milestone 2 |
| Nov 2 2026 | Final submissions due |
| Nov 8 2026 | Papers due |
| Dec 4 2026 | Results announced |
Each task has a grid-based input/output pattern. The model must infer the RULE from 2–5 examples and apply it to a test grid.
Training example 1:
Input: Output:
[[0,0,2], [[0,0,0],
[0,2,0], [0,0,2],
[2,0,0]] [0,2,0]]
Test: → Your model must predict this output
Input:
[[1,0,0],
[0,1,0],
[0,0,1]]
The task above might encode "shift all colored cells down by one". Your model must generalize the rule from examples — not memorize.
Treat ARC as a programming puzzle — search for a program that transforms input → output.
Domain-Specific Language (DSL) approach:
# Example DSL primitives
def rotate_90(grid): return [list(row) for row in zip(*grid[::-1])]
def flip_h(grid): return [row[::-1] for row in grid]
def recolor(grid, from_color, to_color):
return [[to_color if c == from_color else c for c in row] for row in grid]
# Composition search (brute force for 1-2 operations)
from itertools import product
PRIMITIVES = [rotate_90, flip_h, lambda g: flip_h(rotate_90(g))]
def search_program(train_pairs):
"""Find single operation that works on all training pairs."""
for fn in PRIMITIVES:
if all(fn(inp) == out for inp, out in train_pairs):
return fn
return None
Why it works: 80%+ of ARC tasks can be solved with 3–5 chained primitive operations. DSL approaches won the 2024 competition.
Use frontier LLMs with in-context examples. Describe the grid transformation in text and ask the model to infer the rule.
Key finding from 2024: OpenAI's o3 achieved 75.7% on ARC-AGI-1 (previously only 4% with GPT-4). This was a breakthrough moment showing chain-of-thought reasoning helps significantly.
# Prompt template for LLM approach
PROMPT_TEMPLATE = """
You are solving an ARC (Abstraction and Reasoning Corpus) task.
Study the training examples carefully to identify the transformation rule,
then apply it to the test input.
Training Examples:
{training_examples}
Test Input:
{test_input}
First, describe the transformation rule you observe in the training examples.
Then apply this rule step-by-step to the test input.
Output ONLY the final grid as a Python list of lists.
"""
def arc_with_llm(task, model_client):
training_str = "\n".join([
f"Example {i+1}:\nInput: {pair['input']}\nOutput: {pair['output']}"
for i, pair in enumerate(task['train'])
])
prompt = PROMPT_TEMPLATE.format(
training_examples=training_str,
test_input=task['test'][0]['input']
)
return model_client.generate(prompt)
Combine neural network perception with symbolic rule search:
Fine-tune a pretrained vision model on each individual task at test time:
Documented result: TTT improved accuracy by 12–18% on ARC tasks vs static inference.
import json
from pathlib import Path
def load_arc_tasks(data_dir: str):
"""Load all ARC tasks from the standard directory structure."""
tasks = {}
for path in Path(data_dir).glob("*.json"):
with open(path) as f:
task = json.load(f)
tasks[path.stem] = task # key = task ID
return tasks
def display_task(task):
"""Print a task for visual inspection."""
print("=== TRAINING PAIRS ===")
for i, pair in enumerate(task['train']):
print(f"\nPair {i+1}:")
print("Input:")
for row in pair['input']:
print(' '.join(str(c) for c in row))
print("Output:")
for row in pair['output']:
print(' '.join(str(c) for c in row))
print("\n=== TEST INPUT ===")
for row in task['test'][0]['input']:
print(' '.join(str(c) for c in row))
def grid_to_tensor(grid):
"""Convert grid to one-hot tensor for neural approaches."""
import torch
import numpy as np
n_colors = 10 # ARC uses colors 0–9
grid_np = np.array(grid)
H, W = grid_np.shape
one_hot = torch.zeros(n_colors, H, W)
for c in range(n_colors):
one_hot[c] = torch.tensor(grid_np == c, dtype=torch.float)
return one_hot
import numpy as np
def to_np(grid): return np.array(grid)
def to_list(arr): return arr.tolist()
# Geometric transforms
def rot90(g): return to_list(np.rot90(to_np(g)))
def rot180(g): return to_list(np.rot90(to_np(g), 2))
def rot270(g): return to_list(np.rot90(to_np(g), 3))
def flip_h(g): return to_list(np.fliplr(to_np(g)))
def flip_v(g): return to_list(np.flipud(to_np(g)))
def transpose(g): return to_list(np.transpose(to_np(g)))
# Color operations
def recolor(g, from_c, to_c):
a = to_np(g).copy()
a[a == from_c] = to_c
return to_list(a)
def swap_colors(g, c1, c2):
a = to_np(g).copy()
mask1, mask2 = a == c1, a == c2
a[mask1] = c2
a[mask2] = c1
return to_list(a)
# Object extraction
def get_objects(g, background=0):
"""Find connected components (objects) in the grid."""
from scipy import ndimage
a = to_np(g)
labeled, n = ndimage.label(a != background)
objects = []
for i in range(1, n + 1):
mask = labeled == i
rows, cols = np.where(mask)
objects.append({
'color': int(a[rows[0], cols[0]]),
'cells': list(zip(rows.tolist(), cols.tolist())),
'bbox': (rows.min(), cols.min(), rows.max(), cols.max()),
'size': int(mask.sum())
})
return objects
# Grid operations
def crop_to_content(g, background=0):
"""Remove padding rows/columns that are all background."""
a = to_np(g)
rows = np.any(a != background, axis=1)
cols = np.any(a != background, axis=0)
return to_list(a[rows][:, cols])
def tile(g, reps_h, reps_w):
"""Tile the grid reps_h × reps_w times."""
return to_list(np.tile(to_np(g), (reps_h, reps_w)))
def pad(g, top=1, bottom=1, left=1, right=1, fill=0):
return to_list(np.pad(to_np(g), ((top, bottom), (left, right)), constant_values=fill))
def evaluate(prediction, ground_truth):
"""ARC scoring: exact match only (no partial credit)."""
return int(prediction == ground_truth)
def batch_evaluate(predictions, ground_truths):
"""Score a batch — returns fraction correct."""
return sum(evaluate(p, gt) for p, gt in zip(predictions, ground_truths)) / len(predictions)
ARC is binary: you either solve the task or you don't. Partial matches don't count. This makes ensembling different:
Ensembling for ARC: Generate multiple candidate outputs from different approaches and take the most common prediction (plurality vote). If all disagree, submit your best single approach.
| Resource | URL |
|---|---|
| Original ARC paper | arxiv.org/abs/1911.01547 |
| ARC Prize website | arcprize.org |
| 2024 winning solution (Ryan Greenblatt) | arcprize.org/blog/oai-o3-pub-breakthrough |
| MinARC — smallest ARC DSL solver | github.com/michaelhodel/arc-dsl |
| RE-ARC — data augmentation for ARC | github.com/michaelhodel/re-arc |
| ARC Dataset | github.com/fchollet/ARC-AGI |
| Kaggle competition page | kaggle.com/competitions/arc-prize-2025 |
| Top 2024 solutions | kaggle.com/competitions/arc-prize-2024/discussion |