Spaces:
Running
Running
Sync pipeline status
Browse files- README.md +7 -3
- app.js +335 -0
- data/problems.json +1 -0
- data/rejected.json +1 -0
- data/status.json +253 -0
- index.html +99 -18
- style.css +216 -18
README.md
CHANGED
|
@@ -1,10 +1,14 @@
|
|
| 1 |
---
|
| 2 |
title: Beam Verified Python
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
colorTo: green
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
title: Beam Verified Python
|
| 3 |
+
emoji: 🧪
|
| 4 |
+
colorFrom: blue
|
| 5 |
colorTo: green
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
| 8 |
+
license: apache-2.0
|
| 9 |
+
short_description: Python problems written by Beam, kept only if they pass.
|
| 10 |
---
|
| 11 |
|
| 12 |
+
Live status of a synthetic dataset built with [Beam-1.0-501B-A23B](https://huggingface.co/reflection/Beam-1.0-501B-A23B):
|
| 13 |
+
Beam writes a Python exercise, a reference solution and unit tests; a problem is kept only if the
|
| 14 |
+
solution passes every test in a sandbox and the tests reject trivial fake answers.
|
app.js
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const FAKES = ["return None", "return 0", "return ''", "return []", "return False", "return first argument"];
|
| 2 |
+
const REASONS = {
|
| 3 |
+
api_error: ["The API call failed", "Beam never answered (network error, timeout or rate limit). These are retried on the next run."],
|
| 4 |
+
unparseable: ["No readable JSON", "Beam's reply didn't contain the problem in the required format."],
|
| 5 |
+
missing_fields: ["Missing pieces", "The reply lacked a title, prompt, solution or test list."],
|
| 6 |
+
solution_syntax: ["Solution doesn't parse", "The reference solution has a Python syntax error."],
|
| 7 |
+
entry_point_missing: ["Function not defined", "The solution never defines the function the tests call."],
|
| 8 |
+
disallowed_import: ["Unsafe import", "The solution imports a module outside the pure standard-library allowlist."],
|
| 9 |
+
too_few_valid_tests: ["Too few tests", "Fewer than six well-formed assert statements that call the function."],
|
| 10 |
+
timeout: ["Too slow", "Running the tests took longer than the time limit."],
|
| 11 |
+
solution_load_error: ["Solution crashes on load", "Defining the solution raised an error before any test ran."],
|
| 12 |
+
solution_fails_tests: ["Fails its own tests", "Beam's solution and Beam's tests disagree, so at least one of them is wrong."],
|
| 13 |
+
tests_too_weak: ["Tests too weak", "A fake answer like return None passed every test."],
|
| 14 |
+
duplicate: ["Duplicate", "Same problem statement as one already kept."],
|
| 15 |
+
};
|
| 16 |
+
|
| 17 |
+
const $ = (id) => document.getElementById(id);
|
| 18 |
+
const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
| 19 |
+
const fmt = (n) => Number(n || 0).toLocaleString("en-US");
|
| 20 |
+
const el = (tag, cls, text) => {
|
| 21 |
+
const e = document.createElement(tag);
|
| 22 |
+
if (cls) e.className = cls;
|
| 23 |
+
if (text != null) e.textContent = text;
|
| 24 |
+
return e;
|
| 25 |
+
};
|
| 26 |
+
|
| 27 |
+
function ago(iso) {
|
| 28 |
+
const s = Math.max(0, (Date.now() - new Date(iso).getTime()) / 1000);
|
| 29 |
+
if (s < 90) return "just now";
|
| 30 |
+
if (s < 5400) return `${Math.round(s / 60)} minutes ago`;
|
| 31 |
+
if (s < 129600) return `${Math.round(s / 3600)} hours ago`;
|
| 32 |
+
return `${Math.round(s / 86400)} days ago`;
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
function md(text) {
|
| 36 |
+
return DOMPurify.sanitize(marked.parse(text || ""));
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
function highlightIn(root) {
|
| 40 |
+
if (!window.hljs) return;
|
| 41 |
+
root.querySelectorAll("pre code").forEach((b) => {
|
| 42 |
+
if (!b.className) b.className = "language-python";
|
| 43 |
+
hljs.highlightElement(b);
|
| 44 |
+
});
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
/* ---------- header + funnel + ledger ---------- */
|
| 48 |
+
|
| 49 |
+
function renderStatus(status) {
|
| 50 |
+
const generated = status.funnel[0].count;
|
| 51 |
+
const kept = status.funnel[status.funnel.length - 1].count;
|
| 52 |
+
$("bar-status").textContent = `Updated ${ago(status.updated_at)}`;
|
| 53 |
+
const hs = $("headline-status");
|
| 54 |
+
hs.innerHTML = "";
|
| 55 |
+
if (!generated) {
|
| 56 |
+
hs.textContent = "No problems generated yet. Run the generator, then sync this page.";
|
| 57 |
+
return;
|
| 58 |
+
}
|
| 59 |
+
hs.append(el("strong", null, `${fmt(kept)} of ${fmt(generated)}`), ` problems Beam has written so far passed every check.`);
|
| 60 |
+
|
| 61 |
+
const funnel = $("funnel");
|
| 62 |
+
funnel.innerHTML = "";
|
| 63 |
+
for (const stage of status.funnel) {
|
| 64 |
+
const li = el("li");
|
| 65 |
+
const top = el("div", "f-top");
|
| 66 |
+
top.append(el("span", "f-label", stage.label), el("span", "f-count", fmt(stage.count)));
|
| 67 |
+
const bar = el("div", "f-bar");
|
| 68 |
+
const fill = el("span");
|
| 69 |
+
fill.style.width = `${generated ? (100 * stage.count) / generated : 0}%`;
|
| 70 |
+
bar.append(fill);
|
| 71 |
+
const body = el("div");
|
| 72 |
+
body.append(top, bar);
|
| 73 |
+
const lostEntries = Object.entries(stage.lost);
|
| 74 |
+
const lost = el("p", lostEntries.length ? "f-lost" : "f-lost none");
|
| 75 |
+
lost.textContent = lostEntries.length
|
| 76 |
+
? lostEntries.map(([r, n]) => `${fmt(n)} dropped: ${(REASONS[r] || [r])[0].toLowerCase()}`).join("; ")
|
| 77 |
+
: stage.key === "generated" ? "Every reply Beam sent back" : "None dropped here";
|
| 78 |
+
li.append(body, lost);
|
| 79 |
+
funnel.append(li);
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
const t = status.tokens || {};
|
| 83 |
+
const perRow = generated ? (t.completion || 0) / generated : 0;
|
| 84 |
+
const rows = [
|
| 85 |
+
["Beam output tokens", fmt(t.completion), `${fmt(t.reasoning)} of them spent thinking`],
|
| 86 |
+
["Prompt tokens", fmt(t.prompt), null],
|
| 87 |
+
["Output tokens per problem", fmt(Math.round(perRow)), perRow ? `about ${fmt(Math.floor(1e6 / perRow))} problems per million output tokens` : null],
|
| 88 |
+
["Typical call", status.median_seconds_per_call != null ? `${status.median_seconds_per_call}s` : "–", null],
|
| 89 |
+
["Served by", Object.entries(status.providers).map(([p, n]) => `${p} (${fmt(n)})`).join(", ") || "–", null],
|
| 90 |
+
];
|
| 91 |
+
const dl = el("dl");
|
| 92 |
+
for (const [k, v, note] of rows) {
|
| 93 |
+
const dd = el("dd", null, v);
|
| 94 |
+
if (note) dd.append(el("small", null, note));
|
| 95 |
+
dl.append(el("dt", null, k), dd);
|
| 96 |
+
}
|
| 97 |
+
$("ledger").replaceChildren(dl);
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
/* ---------- coverage ---------- */
|
| 101 |
+
|
| 102 |
+
function renderCoverage(status) {
|
| 103 |
+
const topics = Object.keys(status.coverage);
|
| 104 |
+
const half = Math.ceil(topics.length / 2);
|
| 105 |
+
const wrap = $("coverage");
|
| 106 |
+
wrap.innerHTML = "";
|
| 107 |
+
for (const chunk of [topics.slice(0, half), topics.slice(half)]) {
|
| 108 |
+
const col = el("div", "cov-col");
|
| 109 |
+
col.append(el("span"));
|
| 110 |
+
for (const d of status.difficulties) col.append(el("span", "cov-h", d));
|
| 111 |
+
for (const topic of chunk) {
|
| 112 |
+
const label = el("span", "cov-t", topic);
|
| 113 |
+
label.title = topic;
|
| 114 |
+
col.append(label);
|
| 115 |
+
for (const d of status.difficulties) {
|
| 116 |
+
const n = status.coverage[topic][d];
|
| 117 |
+
const c = el("span", n ? "cov-c has" : "cov-c", n ? String(n) : "");
|
| 118 |
+
c.setAttribute("aria-label", `${topic}, ${d}: ${n} problems`);
|
| 119 |
+
col.append(c);
|
| 120 |
+
}
|
| 121 |
+
}
|
| 122 |
+
wrap.append(col);
|
| 123 |
+
}
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
/* ---------- rejections ---------- */
|
| 127 |
+
|
| 128 |
+
function renderRejected(status) {
|
| 129 |
+
const box = $("rejected");
|
| 130 |
+
const entries = Object.entries(status.reasons);
|
| 131 |
+
if (!entries.length) {
|
| 132 |
+
box.replaceChildren(el("p", "rej-empty", "Nothing rejected yet. Every problem Beam has written so far passed all the checks."));
|
| 133 |
+
return;
|
| 134 |
+
}
|
| 135 |
+
const ul = el("ul", "rej-list");
|
| 136 |
+
for (const [r, n] of entries) {
|
| 137 |
+
const [why, desc] = REASONS[r] || [r, ""];
|
| 138 |
+
const li = el("li");
|
| 139 |
+
const text = el("div");
|
| 140 |
+
text.append(el("div", "rej-why", why), el("div", "rej-desc", desc));
|
| 141 |
+
li.append(el("span", "rej-n", fmt(n)), text);
|
| 142 |
+
ul.append(li);
|
| 143 |
+
}
|
| 144 |
+
box.replaceChildren(ul);
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
/* ---------- specimen ---------- */
|
| 148 |
+
|
| 149 |
+
let specTimers = [];
|
| 150 |
+
let specIndex = -1;
|
| 151 |
+
|
| 152 |
+
function signatureOf(p) {
|
| 153 |
+
if (p.signature) return p.signature;
|
| 154 |
+
const m = p.solution.match(new RegExp(`def ${p.entry_point}\\([^)]*\\)[^:]*:`));
|
| 155 |
+
return m ? m[0] : `def ${p.entry_point}(...)`;
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
function showSpecimen(problems) {
|
| 159 |
+
specTimers.forEach(clearTimeout);
|
| 160 |
+
specTimers = [];
|
| 161 |
+
if (!problems.length) {
|
| 162 |
+
$("specimen").replaceChildren(el("p", "spec-note", "The first verified problem will appear here."));
|
| 163 |
+
return;
|
| 164 |
+
}
|
| 165 |
+
specIndex = problems.length === 1 ? 0 : (specIndex + 1 + Math.floor(Math.random() * (problems.length - 1))) % problems.length;
|
| 166 |
+
const p = problems[specIndex];
|
| 167 |
+
const tests = [...p.public_tests, ...p.hidden_tests];
|
| 168 |
+
$("spec-title").textContent = p.title;
|
| 169 |
+
$("spec-tags").textContent = `${p.difficulty}, ${p.topic}`;
|
| 170 |
+
$("spec-sig").textContent = signatureOf(p);
|
| 171 |
+
$("spec-next").hidden = problems.length < 2;
|
| 172 |
+
|
| 173 |
+
const cells = $("spec-cells");
|
| 174 |
+
cells.innerHTML = "";
|
| 175 |
+
tests.forEach((t, i) => {
|
| 176 |
+
const li = el("li", null, "✓");
|
| 177 |
+
li.title = t;
|
| 178 |
+
li.setAttribute("aria-label", `Test ${i + 1} passed`);
|
| 179 |
+
cells.append(li);
|
| 180 |
+
});
|
| 181 |
+
const fakes = $("spec-fakes");
|
| 182 |
+
fakes.innerHTML = "";
|
| 183 |
+
FAKES.forEach((f) => fakes.append(el("li", null, f)));
|
| 184 |
+
const note = $("spec-pass-note");
|
| 185 |
+
note.textContent = "";
|
| 186 |
+
|
| 187 |
+
const cellEls = [...cells.children];
|
| 188 |
+
const fakeEls = [...fakes.children];
|
| 189 |
+
const finish = () => (note.textContent = `${tests.length} of ${tests.length} tests pass. ${p.public_tests.length} are shown to the solver, ${p.hidden_tests.length} are hidden for scoring.`);
|
| 190 |
+
if (reduceMotion) {
|
| 191 |
+
cellEls.forEach((c) => c.classList.add("on"));
|
| 192 |
+
fakeEls.forEach((f) => f.classList.add("caught"));
|
| 193 |
+
finish();
|
| 194 |
+
return;
|
| 195 |
+
}
|
| 196 |
+
cellEls.forEach((c, i) => specTimers.push(setTimeout(() => c.classList.add("on"), 300 + i * 85)));
|
| 197 |
+
const after = 300 + cellEls.length * 85 + 250;
|
| 198 |
+
specTimers.push(setTimeout(finish, after));
|
| 199 |
+
fakeEls.forEach((f, i) => specTimers.push(setTimeout(() => f.classList.add("caught"), after + 200 + i * 160)));
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
/* ---------- browser ---------- */
|
| 203 |
+
|
| 204 |
+
const state = { q: "", diff: "all", current: null };
|
| 205 |
+
|
| 206 |
+
function renderSeg(difficulties) {
|
| 207 |
+
const seg = $("diff-seg");
|
| 208 |
+
for (const d of ["all", ...difficulties]) {
|
| 209 |
+
const b = el("button", null, d === "all" ? "All" : d[0].toUpperCase() + d.slice(1));
|
| 210 |
+
b.type = "button";
|
| 211 |
+
b.setAttribute("role", "radio");
|
| 212 |
+
b.setAttribute("aria-checked", String(d === state.diff));
|
| 213 |
+
b.onclick = () => {
|
| 214 |
+
state.diff = d;
|
| 215 |
+
seg.querySelectorAll("button").forEach((x) => x.setAttribute("aria-checked", String(x === b)));
|
| 216 |
+
renderList();
|
| 217 |
+
};
|
| 218 |
+
seg.append(b);
|
| 219 |
+
}
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
let PROBLEMS = [];
|
| 223 |
+
|
| 224 |
+
function renderList() {
|
| 225 |
+
const q = state.q.trim().toLowerCase();
|
| 226 |
+
const items = PROBLEMS.filter(
|
| 227 |
+
(p) => (state.diff === "all" || p.difficulty === state.diff) && (!q || `${p.title} ${p.topic}`.toLowerCase().includes(q))
|
| 228 |
+
);
|
| 229 |
+
const ul = $("plist");
|
| 230 |
+
ul.innerHTML = "";
|
| 231 |
+
if (!items.length) {
|
| 232 |
+
ul.append(el("li", "none", PROBLEMS.length ? "No problems match. Clear the search or pick another difficulty." : "No verified problems yet."));
|
| 233 |
+
return;
|
| 234 |
+
}
|
| 235 |
+
for (const p of items) {
|
| 236 |
+
const li = el("li");
|
| 237 |
+
const b = el("button");
|
| 238 |
+
b.type = "button";
|
| 239 |
+
b.setAttribute("aria-current", String(p.id === state.current));
|
| 240 |
+
b.append(el("span", "p-title", p.title), el("span", "p-meta", `${p.difficulty}, ${p.topic}, ${p.num_tests} tests`));
|
| 241 |
+
b.onclick = () => showDetail(p);
|
| 242 |
+
li.append(b);
|
| 243 |
+
ul.append(li);
|
| 244 |
+
}
|
| 245 |
+
if (!items.some((p) => p.id === state.current)) showDetail(items[0]);
|
| 246 |
+
}
|
| 247 |
+
|
| 248 |
+
function testList(tests) {
|
| 249 |
+
const ul = el("ul", "tests");
|
| 250 |
+
tests.forEach((t) => ul.append(el("li", null, t)));
|
| 251 |
+
return ul;
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
function showDetail(p) {
|
| 255 |
+
state.current = p.id;
|
| 256 |
+
$("plist").querySelectorAll("button").forEach((b) => b.setAttribute("aria-current", String(b.querySelector(".p-title")?.textContent === p.title)));
|
| 257 |
+
const d = $("detail");
|
| 258 |
+
d.innerHTML = "";
|
| 259 |
+
d.append(el("p", "d-meta", `${p.difficulty}, ${p.topic}. Written by ${p.source_model} at temperature ${p.temperature}.`));
|
| 260 |
+
const prose = el("div", "prose");
|
| 261 |
+
prose.innerHTML = md(p.prompt);
|
| 262 |
+
d.append(prose);
|
| 263 |
+
|
| 264 |
+
const tabs = el("div", "tabs");
|
| 265 |
+
tabs.setAttribute("role", "tablist");
|
| 266 |
+
const panel = el("div", "tabpanel");
|
| 267 |
+
panel.setAttribute("role", "tabpanel");
|
| 268 |
+
const views = {
|
| 269 |
+
"Reference solution": () => {
|
| 270 |
+
const pre = el("pre");
|
| 271 |
+
pre.append(el("code", "language-python", p.solution));
|
| 272 |
+
return pre;
|
| 273 |
+
},
|
| 274 |
+
[`Tests shown to the solver (${p.public_tests.length})`]: () => testList(p.public_tests),
|
| 275 |
+
[`Hidden tests (${p.hidden_tests.length})`]: () => testList(p.hidden_tests),
|
| 276 |
+
};
|
| 277 |
+
Object.keys(views).forEach((name, i) => {
|
| 278 |
+
const b = el("button", null, name);
|
| 279 |
+
b.type = "button";
|
| 280 |
+
b.setAttribute("role", "tab");
|
| 281 |
+
b.setAttribute("aria-selected", String(i === 0));
|
| 282 |
+
b.onclick = () => {
|
| 283 |
+
tabs.querySelectorAll("button").forEach((x) => x.setAttribute("aria-selected", String(x === b)));
|
| 284 |
+
panel.replaceChildren(views[name]());
|
| 285 |
+
highlightIn(panel);
|
| 286 |
+
};
|
| 287 |
+
tabs.append(b);
|
| 288 |
+
});
|
| 289 |
+
panel.append(Object.values(views)[0]());
|
| 290 |
+
d.append(tabs, panel);
|
| 291 |
+
highlightIn(d);
|
| 292 |
+
}
|
| 293 |
+
|
| 294 |
+
/* ---------- footer + boot ---------- */
|
| 295 |
+
|
| 296 |
+
function renderFoot(status) {
|
| 297 |
+
const f = $("foot");
|
| 298 |
+
const p = el("p");
|
| 299 |
+
p.append(
|
| 300 |
+
"Generated with ",
|
| 301 |
+
Object.assign(el("a", null, status.model), { href: "https://huggingface.co/reflection/Beam-1.0-501B-A23B" }),
|
| 302 |
+
" for the Build with Beam challenge. Solutions run in a separate Python process with CPU, memory and time limits, and may import only pure standard-library modules."
|
| 303 |
+
);
|
| 304 |
+
f.replaceChildren(p);
|
| 305 |
+
}
|
| 306 |
+
|
| 307 |
+
async function boot() {
|
| 308 |
+
try {
|
| 309 |
+
const bust = `?t=${Date.now()}`;
|
| 310 |
+
const [status, problems] = await Promise.all([
|
| 311 |
+
fetch(`data/status.json${bust}`).then((r) => r.json()),
|
| 312 |
+
fetch(`data/problems.json${bust}`).then((r) => r.json()),
|
| 313 |
+
]);
|
| 314 |
+
PROBLEMS = problems;
|
| 315 |
+
renderStatus(status);
|
| 316 |
+
renderCoverage(status);
|
| 317 |
+
renderRejected(status);
|
| 318 |
+
renderFoot(status);
|
| 319 |
+
showSpecimen(problems);
|
| 320 |
+
$("spec-next").onclick = () => showSpecimen(problems);
|
| 321 |
+
renderSeg(status.difficulties);
|
| 322 |
+
$("q").addEventListener("input", (e) => {
|
| 323 |
+
state.q = e.target.value;
|
| 324 |
+
renderList();
|
| 325 |
+
});
|
| 326 |
+
renderList();
|
| 327 |
+
} catch (err) {
|
| 328 |
+
$("bar-status").textContent = "Couldn't load the run data";
|
| 329 |
+
document.querySelector("main").replaceChildren(
|
| 330 |
+
el("p", "load-error", `The status files in data/ didn't load (${err.message}). Run beamcode.space_sync to regenerate them.`)
|
| 331 |
+
);
|
| 332 |
+
}
|
| 333 |
+
}
|
| 334 |
+
|
| 335 |
+
document.addEventListener("DOMContentLoaded", boot);
|
data/problems.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
[{"id": "aafeb62b8774", "topic": "shortest paths", "difficulty": "easy", "title": "Shortest Ferry Times", "entry_point": "shortest_ferry_times", "signature": "def shortest_ferry_times(routes: list[tuple[str, str, int]], origin: str) -> dict[str, int]:", "prompt": "## Shortest Ferry Times\n\nA ferry network connects ports. Each route is an undirected ferry crossing with a nonnegative travel time in minutes. Given a list of routes and an origin port, return the shortest travel time from the origin to every reachable port.\n\n### Function signature\n```python\ndef shortest_ferry_times(routes: list[tuple[str, str, int]], origin: str) -> dict[str, int]:\n```\n\n### Input\n- `routes`: a list of tuples `(port_a, port_b, minutes)`.\n- Port names are strings.\n- `minutes` is a nonnegative integer.\n- A route may be used in either direction.\n- Duplicate routes, self-loops, and zero-minute crossings are allowed.\n\n### Output\n- A dictionary mapping each reachable port to its minimum travel time from `origin`.\n- The origin is always included with time `0`, even if it has no routes.\n- Ports that are unreachable from the origin are omitted.\n- If multiple routes connect the same two ports, the shorter effective time is used automatically by shortest-path computation.\n\n### Constraints\n- `0 <= len(routes) <= 1000`\n- Port names contain at most 32 characters.\n- `0 <= minutes <= 10**6`\n- All route endpoints and the origin are valid port names.\n\n### Examples\n```python\nshortest_ferry_times([(\"A\", \"B\", 10), (\"B\", \"C\", 10), (\"A\", \"C\", 15)], \"A\")\n# {\"A\": 0, \"B\": 10, \"C\": 15}\n\nshortest_ferry_times([(\"X\", \"Y\", 7)], \"A\")\n# {\"A\": 0}\n```", "solution": "import heapq\n\n\ndef shortest_ferry_times(routes: list[tuple[str, str, int]], origin: str) -> dict[str, int]:\n \"\"\"Return shortest travel times from origin in an undirected weighted graph.\"\"\"\n graph: dict[str, list[tuple[str, int]]] = {}\n\n def add_edge(a: str, b: str, weight: int) -> None:\n graph.setdefault(a, []).append((b, weight))\n if a != b:\n graph.setdefault(b, []).append((a, weight))\n else:\n graph.setdefault(b, [])\n\n for port_a, port_b, minutes in routes:\n add_edge(port_a, port_b, minutes)\n\n distances: dict[str, int] = {origin: 0}\n priority_queue: list[tuple[int, str]] = [(0, origin)]\n\n while priority_queue:\n current_distance, current_port = heapq.heappop(priority_queue)\n if current_distance > distances.get(current_port, float(\"inf\")):\n continue\n\n for neighbor, weight in graph.get(current_port, []):\n candidate = current_distance + weight\n if candidate < distances.get(neighbor, float(\"inf\")):\n distances[neighbor] = candidate\n heapq.heappush(priority_queue, (candidate, neighbor))\n\n return distances\n", "public_tests": ["assert shortest_ferry_times([], \"A\") == {\"A\": 0}", "assert shortest_ferry_times([(\"A\", \"B\", 5)], \"A\") == {\"A\": 0, \"B\": 5}", "assert shortest_ferry_times([(\"A\", \"B\", 5)], \"B\") == {\"B\": 0, \"A\": 5}"], "hidden_tests": ["assert shortest_ferry_times([(\"A\", \"B\", 10), (\"B\", \"C\", 10), (\"A\", \"C\", 15)], \"A\") == {\"A\": 0, \"B\": 10, \"C\": 15}", "assert shortest_ferry_times([(\"A\", \"B\", 1), (\"C\", \"D\", 2)], \"A\") == {\"A\": 0, \"B\": 1}", "assert shortest_ferry_times([(\"A\", \"B\", 8), (\"A\", \"B\", 3)], \"A\") == {\"A\": 0, \"B\": 3}", "assert shortest_ferry_times([(\"A\", \"B\", 0), (\"B\", \"C\", 4)], \"A\") == {\"A\": 0, \"B\": 0, \"C\": 4}", "assert shortest_ferry_times([(\"A\", \"A\", 99), (\"A\", \"B\", 2)], \"A\") == {\"A\": 0, \"B\": 2}", "assert shortest_ferry_times([(\"X\", \"Y\", 7)], \"A\") == {\"A\": 0}", "assert shortest_ferry_times([(\"A\", \"B\", 2), (\"A\", \"C\", 2), (\"B\", \"D\", 2), (\"C\", \"D\", 2)], \"A\") == {\"A\": 0, \"B\": 2, \"C\": 2, \"D\": 4}", "assert shortest_ferry_times([(\"A\", \"B\", 0), (\"B\", \"C\", 0), (\"C\", \"A\", 0), (\"C\", \"D\", 1)], \"A\") == {\"A\": 0, \"B\": 0, \"C\": 0, \"D\": 1}", "assert shortest_ferry_times([(\"B\", \"A\", 6)], \"A\") == {\"A\": 0, \"B\": 6}", "assert shortest_ferry_times([(\"A\", \"B\", 1), (\"B\", \"C\", 1), (\"A\", \"C\", 3)], \"A\") == {\"A\": 0, \"B\": 1, \"C\": 2}", "assert shortest_ferry_times([(\"A\", \"B\", 10), (\"B\", \"C\", 10), (\"A\", \"C\", 25)], \"A\") == {\"A\": 0, \"B\": 10, \"C\": 20}"], "num_tests": 14, "source_model": "reflection/Beam-1.0-501B-A23B", "temperature": 0.8}, {"id": "ab37e43f0c9c", "topic": "version strings and semantic comparison", "difficulty": "medium", "title": "Semantic Version Comparator", "entry_point": "compare_versions", "signature": "def compare_versions(a: str, b: str) -> int:", "prompt": "## Semantic Version Comparator\n\nYou are comparing firmware release tags for a medical-device update service. Implement a function that compares two version strings according to semantic-version precedence.\n\n**Signature**\n\n```python\ndef compare_versions(a: str, b: str) -> int:\n```\n\n**Version grammar**\n\nA valid version string has the form:\n\n```\nMAJOR.MINOR.PATCH[-prerelease][+build]\n```\n\n- `MAJOR`, `MINOR`, and `PATCH` are non-negative integers without leading zeros.\n- `prerelease` is a dot-separated list of identifiers. Each identifier is either a non-negative integer without leading zeros, or an ASCII alphanumeric/hyphen string containing at least one non-digit.\n- `build` is a dot-separated list of ASCII alphanumeric/hyphen identifiers.\n- Inputs are guaranteed to be valid version strings.\n\n**Precedence rules**\n\n1. Compare `MAJOR`, then `MINOR`, then `PATCH` numerically.\n2. A version without a prerelease has higher precedence than the same core version with a prerelease.\n3. Prerelease identifiers are compared left to right:\n - Numeric identifiers are compared numerically.\n - Non-numeric identifiers are compared by ASCII lexicographic order.\n - Numeric identifiers always have lower precedence than non-numeric identifiers.\n - If all compared identifiers are equal, the prerelease with more identifiers has higher precedence.\n4. Build metadata is ignored for precedence.\n\n**Return value**\n\nReturn `-1` if `a` has lower precedence than `b`, `0` if they have equal precedence, and `1` if `a` has higher precedence.\n\n**Examples**\n\n- `compare_versions(\"1.2.3-rc.1\", \"1.2.3-rc.10\")` returns `-1` because `1 < 10` numerically.\n- `compare_versions(\"1.0.0+exp.42\", \"1.0.0\")` returns `0` because build metadata is ignored.", "solution": "import re\n\n_VERSION_RE = re.compile(\n r\"^(?P<core>(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*))\"\n r\"(?:-(?P<pre>[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?\"\n r\"(?:\\+(?P<build>[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?$\"\n)\n\n\ndef _parse(version: str):\n match = _VERSION_RE.fullmatch(version)\n if match is None:\n raise ValueError(f\"invalid version string: {version!r}\")\n core = tuple(int(part) for part in match.group(\"core\").split(\".\"))\n pre = match.group(\"pre\")\n prerelease = None if pre is None else pre.split(\".\")\n return core, prerelease\n\n\ndef _compare_identifier(left: str, right: str) -> int:\n left_numeric = left.isdigit()\n right_numeric = right.isdigit()\n if left_numeric and right_numeric:\n left_value = int(left)\n right_value = int(right)\n if left_value < right_value:\n return -1\n if left_value > right_value:\n return 1\n return 0\n if left_numeric != right_numeric:\n return -1 if left_numeric else 1\n if left < right:\n return -1\n if left > right:\n return 1\n return 0\n\n\ndef compare_versions(a: str, b: str) -> int:\n core_a, pre_a = _parse(a)\n core_b, pre_b = _parse(b)\n\n if core_a < core_b:\n return -1\n if core_a > core_b:\n return 1\n\n if pre_a is None and pre_b is None:\n return 0\n if pre_a is None:\n return 1\n if pre_b is None:\n return -1\n\n limit = min(len(pre_a), len(pre_b))\n for index in range(limit):\n result = _compare_identifier(pre_a[index], pre_b[index])\n if result != 0:\n return result\n\n if len(pre_a) == len(pre_b):\n return 0\n return -1 if len(pre_a) < len(pre_b) else 1\n", "public_tests": ["assert compare_versions('1.2.3', '1.2.4') == -1", "assert compare_versions('2.0.0', '1.9.9') == 1", "assert compare_versions('1.0.0', '1.0.0') == 0"], "hidden_tests": ["assert compare_versions('1.0.0-alpha', '1.0.0') == -1", "assert compare_versions('1.0.0', '1.0.0-alpha') == 1", "assert compare_versions('1.0.0-alpha', '1.0.0-beta') == -1", "assert compare_versions('1.0.0-rc.1', '1.0.0-rc.10') == -1", "assert compare_versions('1.0.0-1', '1.0.0-alpha') == -1", "assert compare_versions('1.0.0+build.2', '1.0.0+build.1') == 0", "assert compare_versions('1.0.0-alpha+build', '1.0.0-alpha') == 0", "assert compare_versions('1.0.0-rc.1.0', '1.0.0-rc.1') == 1", "assert compare_versions('1.0.0-alpha.1', '1.0.0-alpha.beta') == -1", "assert compare_versions('0.0.0', '0.0.1') == -1"], "num_tests": 13, "source_model": "reflection/Beam-1.0-501B-A23B", "temperature": 0.8}, {"id": "1bf5bda6cb2c", "topic": "text formatting and wrapping", "difficulty": "easy", "title": "Wrap Plain-Text Labels", "entry_point": "wrap_text", "signature": "def wrap_text(text: str, width: int) -> list[str]:", "prompt": "Write a function `wrap_text(text, width)` that wraps a single line of text into lines of at most `width` characters.\n\nWords are maximal runs of non-whitespace characters. Any whitespace separates words, and output lines contain single spaces between words. Words are packed greedily: put as many whole words on a line as possible without exceeding `width`. If a word is longer than `width`, split it into chunks of at most `width` characters. Empty or whitespace-only input returns `[]`. `width` must be a positive integer.\n\nExamples:\n- `wrap_text('ab cdefg hi', 4)` returns `['ab', 'cdef', 'g hi']`\n- `wrap_text('x abcdefghij y', 4)` returns `['x', 'abcd', 'efgh', 'ij y']`", "solution": "def wrap_text(text: str, width: int) -> list[str]:\n if not isinstance(width, int) or width < 1:\n raise ValueError('width must be a positive integer')\n\n words = text.split()\n lines = []\n current = ''\n\n for word in words:\n if current and len(current) + 1 + len(word) <= width:\n current += ' ' + word\n else:\n if current:\n lines.append(current)\n current = ''\n\n if len(word) <= width:\n current = word\n else:\n start = 0\n n = len(word)\n while start + width < n:\n lines.append(word[start:start + width])\n start += width\n current = word[start:]\n\n if current:\n lines.append(current)\n\n return lines\n", "public_tests": ["assert wrap_text('', 4) == []", "assert wrap_text(' \\t ', 4) == []", "assert wrap_text('hello', 5) == ['hello']"], "hidden_tests": ["assert wrap_text('hello', 3) == ['hel', 'lo']", "assert wrap_text('hello world', 5) == ['hello', 'world']", "assert wrap_text('a b c d e', 5) == ['a b c', 'd e']", "assert wrap_text(' a b ', 10) == ['a b']", "assert wrap_text('abc def', 3) == ['abc', 'def']", "assert wrap_text('abcdefghij', 4) == ['abcd', 'efgh', 'ij']", "assert wrap_text('ab cdefg hi', 4) == ['ab', 'cdef', 'g hi']", "assert wrap_text('x abcdefghij y', 4) == ['x', 'abcd', 'efgh', 'ij y']", "assert wrap_text('abcdefghij k', 4) == ['abcd', 'efgh', 'ij k']", "assert wrap_text('a bc', 1) == ['a', 'b', 'c']", "assert wrap_text('ab cdefghij k', 4) == ['ab', 'cdef', 'ghij', 'k']"], "num_tests": 14, "source_model": "reflection/Beam-1.0-501B-A23B", "temperature": 0.8}]
|
data/rejected.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
[]
|
data/status.json
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"updated_at": "2026-10-30T22:02:17+00:00",
|
| 3 |
+
"model": "Beam-1.0-501B-A23B",
|
| 4 |
+
"providers": {
|
| 5 |
+
"baseten": 3
|
| 6 |
+
},
|
| 7 |
+
"funnel": [
|
| 8 |
+
{
|
| 9 |
+
"key": "generated",
|
| 10 |
+
"label": "Beam wrote it",
|
| 11 |
+
"count": 3,
|
| 12 |
+
"lost": {}
|
| 13 |
+
},
|
| 14 |
+
{
|
| 15 |
+
"key": "well_formed",
|
| 16 |
+
"label": "Well-formed",
|
| 17 |
+
"count": 3,
|
| 18 |
+
"lost": {}
|
| 19 |
+
},
|
| 20 |
+
{
|
| 21 |
+
"key": "passes_tests",
|
| 22 |
+
"label": "Passes its own tests",
|
| 23 |
+
"count": 3,
|
| 24 |
+
"lost": {}
|
| 25 |
+
},
|
| 26 |
+
{
|
| 27 |
+
"key": "beats_fakes",
|
| 28 |
+
"label": "Catches fake answers",
|
| 29 |
+
"count": 3,
|
| 30 |
+
"lost": {}
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"key": "kept",
|
| 34 |
+
"label": "Not a duplicate",
|
| 35 |
+
"count": 3,
|
| 36 |
+
"lost": {}
|
| 37 |
+
}
|
| 38 |
+
],
|
| 39 |
+
"reasons": {},
|
| 40 |
+
"tokens": {
|
| 41 |
+
"prompt": 1142,
|
| 42 |
+
"completion": 15554,
|
| 43 |
+
"reasoning": 11894
|
| 44 |
+
},
|
| 45 |
+
"difficulties": [
|
| 46 |
+
"easy",
|
| 47 |
+
"medium",
|
| 48 |
+
"hard"
|
| 49 |
+
],
|
| 50 |
+
"coverage": {
|
| 51 |
+
"string manipulation": {
|
| 52 |
+
"easy": 0,
|
| 53 |
+
"medium": 0,
|
| 54 |
+
"hard": 0
|
| 55 |
+
},
|
| 56 |
+
"parsing structured text": {
|
| 57 |
+
"easy": 0,
|
| 58 |
+
"medium": 0,
|
| 59 |
+
"hard": 0
|
| 60 |
+
},
|
| 61 |
+
"run-length and other encodings": {
|
| 62 |
+
"easy": 0,
|
| 63 |
+
"medium": 0,
|
| 64 |
+
"hard": 0
|
| 65 |
+
},
|
| 66 |
+
"regular-expression-free tokenizing": {
|
| 67 |
+
"easy": 0,
|
| 68 |
+
"medium": 0,
|
| 69 |
+
"hard": 0
|
| 70 |
+
},
|
| 71 |
+
"arrays and prefix sums": {
|
| 72 |
+
"easy": 0,
|
| 73 |
+
"medium": 0,
|
| 74 |
+
"hard": 0
|
| 75 |
+
},
|
| 76 |
+
"two pointers": {
|
| 77 |
+
"easy": 0,
|
| 78 |
+
"medium": 0,
|
| 79 |
+
"hard": 0
|
| 80 |
+
},
|
| 81 |
+
"sliding window": {
|
| 82 |
+
"easy": 0,
|
| 83 |
+
"medium": 0,
|
| 84 |
+
"hard": 0
|
| 85 |
+
},
|
| 86 |
+
"binary search on answers": {
|
| 87 |
+
"easy": 0,
|
| 88 |
+
"medium": 0,
|
| 89 |
+
"hard": 0
|
| 90 |
+
},
|
| 91 |
+
"sorting with custom keys": {
|
| 92 |
+
"easy": 0,
|
| 93 |
+
"medium": 0,
|
| 94 |
+
"hard": 0
|
| 95 |
+
},
|
| 96 |
+
"hash maps and counting": {
|
| 97 |
+
"easy": 0,
|
| 98 |
+
"medium": 0,
|
| 99 |
+
"hard": 0
|
| 100 |
+
},
|
| 101 |
+
"stacks and bracket matching": {
|
| 102 |
+
"easy": 0,
|
| 103 |
+
"medium": 0,
|
| 104 |
+
"hard": 0
|
| 105 |
+
},
|
| 106 |
+
"queues and simulation": {
|
| 107 |
+
"easy": 0,
|
| 108 |
+
"medium": 0,
|
| 109 |
+
"hard": 0
|
| 110 |
+
},
|
| 111 |
+
"heaps and top-k": {
|
| 112 |
+
"easy": 0,
|
| 113 |
+
"medium": 0,
|
| 114 |
+
"hard": 0
|
| 115 |
+
},
|
| 116 |
+
"intervals and merging": {
|
| 117 |
+
"easy": 0,
|
| 118 |
+
"medium": 0,
|
| 119 |
+
"hard": 0
|
| 120 |
+
},
|
| 121 |
+
"greedy scheduling": {
|
| 122 |
+
"easy": 0,
|
| 123 |
+
"medium": 0,
|
| 124 |
+
"hard": 0
|
| 125 |
+
},
|
| 126 |
+
"dynamic programming on sequences": {
|
| 127 |
+
"easy": 0,
|
| 128 |
+
"medium": 0,
|
| 129 |
+
"hard": 0
|
| 130 |
+
},
|
| 131 |
+
"dynamic programming on grids": {
|
| 132 |
+
"easy": 0,
|
| 133 |
+
"medium": 0,
|
| 134 |
+
"hard": 0
|
| 135 |
+
},
|
| 136 |
+
"knapsack-style optimization": {
|
| 137 |
+
"easy": 0,
|
| 138 |
+
"medium": 0,
|
| 139 |
+
"hard": 0
|
| 140 |
+
},
|
| 141 |
+
"graph traversal (BFS/DFS) on adjacency lists": {
|
| 142 |
+
"easy": 0,
|
| 143 |
+
"medium": 0,
|
| 144 |
+
"hard": 0
|
| 145 |
+
},
|
| 146 |
+
"shortest paths": {
|
| 147 |
+
"easy": 1,
|
| 148 |
+
"medium": 0,
|
| 149 |
+
"hard": 0
|
| 150 |
+
},
|
| 151 |
+
"topological sort and dependencies": {
|
| 152 |
+
"easy": 0,
|
| 153 |
+
"medium": 0,
|
| 154 |
+
"hard": 0
|
| 155 |
+
},
|
| 156 |
+
"union-find": {
|
| 157 |
+
"easy": 0,
|
| 158 |
+
"medium": 0,
|
| 159 |
+
"hard": 0
|
| 160 |
+
},
|
| 161 |
+
"grid and matrix puzzles": {
|
| 162 |
+
"easy": 0,
|
| 163 |
+
"medium": 0,
|
| 164 |
+
"hard": 0
|
| 165 |
+
},
|
| 166 |
+
"trees encoded as nested lists or parent arrays": {
|
| 167 |
+
"easy": 0,
|
| 168 |
+
"medium": 0,
|
| 169 |
+
"hard": 0
|
| 170 |
+
},
|
| 171 |
+
"recursion and backtracking": {
|
| 172 |
+
"easy": 0,
|
| 173 |
+
"medium": 0,
|
| 174 |
+
"hard": 0
|
| 175 |
+
},
|
| 176 |
+
"combinatorics": {
|
| 177 |
+
"easy": 0,
|
| 178 |
+
"medium": 0,
|
| 179 |
+
"hard": 0
|
| 180 |
+
},
|
| 181 |
+
"number theory": {
|
| 182 |
+
"easy": 0,
|
| 183 |
+
"medium": 0,
|
| 184 |
+
"hard": 0
|
| 185 |
+
},
|
| 186 |
+
"bit manipulation": {
|
| 187 |
+
"easy": 0,
|
| 188 |
+
"medium": 0,
|
| 189 |
+
"hard": 0
|
| 190 |
+
},
|
| 191 |
+
"geometry with integer coordinates": {
|
| 192 |
+
"easy": 0,
|
| 193 |
+
"medium": 0,
|
| 194 |
+
"hard": 0
|
| 195 |
+
},
|
| 196 |
+
"date and time arithmetic with the datetime module": {
|
| 197 |
+
"easy": 0,
|
| 198 |
+
"medium": 0,
|
| 199 |
+
"hard": 0
|
| 200 |
+
},
|
| 201 |
+
"state machines": {
|
| 202 |
+
"easy": 0,
|
| 203 |
+
"medium": 0,
|
| 204 |
+
"hard": 0
|
| 205 |
+
},
|
| 206 |
+
"inventory and order-processing business logic": {
|
| 207 |
+
"easy": 0,
|
| 208 |
+
"medium": 0,
|
| 209 |
+
"hard": 0
|
| 210 |
+
},
|
| 211 |
+
"bank ledger and transaction reconciliation": {
|
| 212 |
+
"easy": 0,
|
| 213 |
+
"medium": 0,
|
| 214 |
+
"hard": 0
|
| 215 |
+
},
|
| 216 |
+
"text formatting and wrapping": {
|
| 217 |
+
"easy": 1,
|
| 218 |
+
"medium": 0,
|
| 219 |
+
"hard": 0
|
| 220 |
+
},
|
| 221 |
+
"version strings and semantic comparison": {
|
| 222 |
+
"easy": 0,
|
| 223 |
+
"medium": 1,
|
| 224 |
+
"hard": 0
|
| 225 |
+
},
|
| 226 |
+
"file-path normalization (pure string logic)": {
|
| 227 |
+
"easy": 0,
|
| 228 |
+
"medium": 0,
|
| 229 |
+
"hard": 0
|
| 230 |
+
},
|
| 231 |
+
"game rules simulation": {
|
| 232 |
+
"easy": 0,
|
| 233 |
+
"medium": 0,
|
| 234 |
+
"hard": 0
|
| 235 |
+
},
|
| 236 |
+
"elevator or traffic simulation": {
|
| 237 |
+
"easy": 0,
|
| 238 |
+
"medium": 0,
|
| 239 |
+
"hard": 0
|
| 240 |
+
},
|
| 241 |
+
"spreadsheet-style formula evaluation": {
|
| 242 |
+
"easy": 0,
|
| 243 |
+
"medium": 0,
|
| 244 |
+
"hard": 0
|
| 245 |
+
},
|
| 246 |
+
"data validation rules": {
|
| 247 |
+
"easy": 0,
|
| 248 |
+
"medium": 0,
|
| 249 |
+
"hard": 0
|
| 250 |
+
}
|
| 251 |
+
},
|
| 252 |
+
"median_seconds_per_call": 9.2
|
| 253 |
+
}
|
index.html
CHANGED
|
@@ -1,19 +1,100 @@
|
|
| 1 |
-
<!
|
| 2 |
-
<html>
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
</html>
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="utf-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
| 6 |
+
<title>Beam Verified Python</title>
|
| 7 |
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 8 |
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 9 |
+
<link href="https://fonts.googleapis.com/css2?family=Schibsted+Grotesk:wght@400;500;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
| 10 |
+
<link rel="stylesheet" href="style.css">
|
| 11 |
+
<script src="https://cdn.jsdelivr.net/npm/marked@12/marked.min.js" defer></script>
|
| 12 |
+
<script src="https://cdn.jsdelivr.net/npm/dompurify@3/dist/purify.min.js" defer></script>
|
| 13 |
+
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11/build/highlight.min.js" defer></script>
|
| 14 |
+
<script src="app.js" defer></script>
|
| 15 |
+
</head>
|
| 16 |
+
<body>
|
| 17 |
+
<header class="bar">
|
| 18 |
+
<span class="wordmark">Beam Verified Python</span>
|
| 19 |
+
<span class="bar-status" id="bar-status">Loading the latest run…</span>
|
| 20 |
+
</header>
|
| 21 |
+
|
| 22 |
+
<main>
|
| 23 |
+
<section class="hero">
|
| 24 |
+
<div class="hero-copy">
|
| 25 |
+
<h1>Python problems written by Beam, kept only if they pass their own tests.</h1>
|
| 26 |
+
<p class="lede">
|
| 27 |
+
Beam writes an exercise, a reference solution and a set of unit tests. We run the solution against every test
|
| 28 |
+
in a sandbox, then try to fool the tests with fake answers. A problem only makes it into the dataset if the
|
| 29 |
+
solution passes and every fake answer gets caught.
|
| 30 |
+
</p>
|
| 31 |
+
<p class="headline-status" id="headline-status"></p>
|
| 32 |
+
</div>
|
| 33 |
+
|
| 34 |
+
<figure class="specimen" id="specimen" aria-label="One verified problem">
|
| 35 |
+
<figcaption class="spec-head">
|
| 36 |
+
<span class="spec-title" id="spec-title"></span>
|
| 37 |
+
<span class="spec-tags" id="spec-tags"></span>
|
| 38 |
+
</figcaption>
|
| 39 |
+
<code class="spec-sig" id="spec-sig"></code>
|
| 40 |
+
<div class="spec-row">
|
| 41 |
+
<h3>Reference solution vs. its own tests</h3>
|
| 42 |
+
<ol class="cells" id="spec-cells"></ol>
|
| 43 |
+
<p class="spec-note" id="spec-pass-note"></p>
|
| 44 |
+
</div>
|
| 45 |
+
<div class="spec-row">
|
| 46 |
+
<h3>Fake answers the tests caught</h3>
|
| 47 |
+
<ul class="fakes" id="spec-fakes"></ul>
|
| 48 |
+
</div>
|
| 49 |
+
<button class="ghost" id="spec-next" type="button">Show another problem</button>
|
| 50 |
+
</figure>
|
| 51 |
+
</section>
|
| 52 |
+
|
| 53 |
+
<section class="block" aria-labelledby="funnel-h">
|
| 54 |
+
<div class="block-head">
|
| 55 |
+
<h2 id="funnel-h">Where problems drop out</h2>
|
| 56 |
+
<p>Each step removes problems that fail it. The last bar is what ships in the dataset.</p>
|
| 57 |
+
</div>
|
| 58 |
+
<div class="funnel-wrap">
|
| 59 |
+
<ol class="funnel" id="funnel"></ol>
|
| 60 |
+
<aside class="ledger" id="ledger" aria-label="Run costs"></aside>
|
| 61 |
+
</div>
|
| 62 |
+
</section>
|
| 63 |
+
|
| 64 |
+
<section class="block" aria-labelledby="cov-h">
|
| 65 |
+
<div class="block-head">
|
| 66 |
+
<h2 id="cov-h">Coverage</h2>
|
| 67 |
+
<p>Verified problems by topic and difficulty. Empty squares are combinations Beam hasn't produced yet.</p>
|
| 68 |
+
</div>
|
| 69 |
+
<div class="coverage" id="coverage"></div>
|
| 70 |
+
</section>
|
| 71 |
+
|
| 72 |
+
<section class="block" aria-labelledby="rej-h">
|
| 73 |
+
<div class="block-head">
|
| 74 |
+
<h2 id="rej-h">Rejected problems</h2>
|
| 75 |
+
<p>Why Beam's output got thrown away.</p>
|
| 76 |
+
</div>
|
| 77 |
+
<div id="rejected"></div>
|
| 78 |
+
</section>
|
| 79 |
+
|
| 80 |
+
<section class="block" aria-labelledby="browse-h">
|
| 81 |
+
<div class="block-head">
|
| 82 |
+
<h2 id="browse-h">Browse problems</h2>
|
| 83 |
+
<p>Everything that passed. Tests shown to the solver appear in the prompt; hidden tests decide the reward.</p>
|
| 84 |
+
</div>
|
| 85 |
+
<div class="browser">
|
| 86 |
+
<div class="list-pane">
|
| 87 |
+
<div class="filters">
|
| 88 |
+
<input type="search" id="q" placeholder="Search titles and topics" aria-label="Search problems">
|
| 89 |
+
<div class="seg" role="radiogroup" aria-label="Difficulty" id="diff-seg"></div>
|
| 90 |
+
</div>
|
| 91 |
+
<ul class="plist" id="plist"></ul>
|
| 92 |
+
</div>
|
| 93 |
+
<article class="detail" id="detail" aria-live="polite"></article>
|
| 94 |
+
</div>
|
| 95 |
+
</section>
|
| 96 |
+
</main>
|
| 97 |
+
|
| 98 |
+
<footer class="foot" id="foot"></footer>
|
| 99 |
+
</body>
|
| 100 |
</html>
|
style.css
CHANGED
|
@@ -1,28 +1,226 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
body {
|
| 2 |
-
|
| 3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
}
|
|
|
|
| 5 |
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
}
|
|
|
|
| 10 |
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
border-radius: 16px;
|
| 24 |
}
|
| 25 |
|
| 26 |
-
|
| 27 |
-
|
| 28 |
}
|
|
|
|
| 1 |
+
:root {
|
| 2 |
+
--prussian: #0f2a52;
|
| 3 |
+
--deep: #0a1f3f;
|
| 4 |
+
--line: #2c4b7a;
|
| 5 |
+
--paper: #eef3f8;
|
| 6 |
+
--muted: #9db2cf;
|
| 7 |
+
--pass: #8ee3b8;
|
| 8 |
+
--fail: #f4b860;
|
| 9 |
+
--sans: "Schibsted Grotesk", system-ui, sans-serif;
|
| 10 |
+
--mono: "JetBrains Mono", ui-monospace, monospace;
|
| 11 |
+
--measure: 66ch;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
* { box-sizing: border-box; }
|
| 15 |
+
|
| 16 |
+
html { background: var(--prussian); }
|
| 17 |
+
|
| 18 |
body {
|
| 19 |
+
margin: 0;
|
| 20 |
+
color: var(--paper);
|
| 21 |
+
font: 400 17px/1.55 var(--sans);
|
| 22 |
+
/* Cyanotype blueprint grid */
|
| 23 |
+
background-color: var(--prussian);
|
| 24 |
+
background-image:
|
| 25 |
+
linear-gradient(rgba(238, 243, 248, 0.045) 1px, transparent 1px),
|
| 26 |
+
linear-gradient(90deg, rgba(238, 243, 248, 0.045) 1px, transparent 1px);
|
| 27 |
+
background-size: 28px 28px;
|
| 28 |
+
-webkit-font-smoothing: antialiased;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
:focus-visible { outline: 2px solid var(--pass); outline-offset: 3px; }
|
| 32 |
+
|
| 33 |
+
h1, h2, h3 { margin: 0; font-weight: 800; letter-spacing: -0.02em; }
|
| 34 |
+
p { margin: 0; }
|
| 35 |
+
code, pre { font-family: var(--mono); }
|
| 36 |
+
|
| 37 |
+
/* Header bar */
|
| 38 |
+
.bar {
|
| 39 |
+
display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; flex-wrap: wrap;
|
| 40 |
+
padding: 1.1rem clamp(1.25rem, 4vw, 3.5rem);
|
| 41 |
+
border-bottom: 1px solid var(--line);
|
| 42 |
+
}
|
| 43 |
+
.wordmark { font-weight: 800; letter-spacing: -0.01em; }
|
| 44 |
+
.bar-status { color: var(--muted); font-size: 0.9rem; }
|
| 45 |
+
|
| 46 |
+
main { padding: 0 clamp(1.25rem, 4vw, 3.5rem); max-width: 1320px; margin: 0 auto; }
|
| 47 |
+
|
| 48 |
+
/* Hero */
|
| 49 |
+
.hero {
|
| 50 |
+
display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: clamp(2rem, 5vw, 5rem);
|
| 51 |
+
align-items: start; padding: clamp(3rem, 8vw, 6.5rem) 0 clamp(3rem, 6vw, 5rem);
|
| 52 |
+
}
|
| 53 |
+
.hero h1 {
|
| 54 |
+
font-size: clamp(2.3rem, 4.6vw, 4.1rem); line-height: 1.02; letter-spacing: -0.035em; max-width: 16ch;
|
| 55 |
+
}
|
| 56 |
+
.lede { margin-top: 1.6rem; max-width: 52ch; color: var(--muted); font-size: 1.06rem; }
|
| 57 |
+
.headline-status { margin-top: 1.8rem; font-size: 1.15rem; font-weight: 500; max-width: 40ch; }
|
| 58 |
+
.headline-status strong { color: var(--pass); font-weight: 700; }
|
| 59 |
+
|
| 60 |
+
/* Specimen: one problem on the test bench */
|
| 61 |
+
.specimen {
|
| 62 |
+
margin: 0; padding: 1.6rem 1.6rem 1.3rem;
|
| 63 |
+
background: var(--deep); border: 1px solid var(--line); border-radius: 4px;
|
| 64 |
+
box-shadow: 10px 10px 0 rgba(10, 31, 63, 0.55);
|
| 65 |
+
}
|
| 66 |
+
.spec-head { display: flex; justify-content: space-between; gap: 1rem; align-items: baseline; flex-wrap: wrap; }
|
| 67 |
+
.spec-title { font-size: 1.35rem; font-weight: 700; letter-spacing: -0.015em; }
|
| 68 |
+
.spec-tags { color: var(--muted); font-size: 0.88rem; }
|
| 69 |
+
.spec-sig {
|
| 70 |
+
display: block; margin-top: 0.9rem; padding: 0.7rem 0.85rem; overflow-x: auto; white-space: pre;
|
| 71 |
+
font-size: 0.82rem; color: var(--paper); background: rgba(238, 243, 248, 0.05); border-radius: 3px;
|
| 72 |
+
}
|
| 73 |
+
.spec-row { margin-top: 1.4rem; }
|
| 74 |
+
.spec-row h3 { font-size: 0.92rem; font-weight: 500; color: var(--muted); letter-spacing: 0; margin-bottom: 0.6rem; }
|
| 75 |
+
|
| 76 |
+
.cells { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
|
| 77 |
+
.cells li {
|
| 78 |
+
width: 26px; height: 26px; border: 1px solid var(--line); border-radius: 3px;
|
| 79 |
+
display: grid; place-items: center; font: 500 0.66rem var(--mono); color: transparent;
|
| 80 |
+
transition: background-color 180ms ease, border-color 180ms ease, color 180ms ease;
|
| 81 |
+
}
|
| 82 |
+
.cells li.on { background: var(--pass); border-color: var(--pass); color: var(--deep); }
|
| 83 |
+
.spec-note { margin-top: 0.55rem; font-size: 0.88rem; color: var(--muted); min-height: 1.4em; }
|
| 84 |
+
|
| 85 |
+
.fakes { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px 8px; }
|
| 86 |
+
.fakes li {
|
| 87 |
+
font: 400 0.8rem var(--mono); padding: 0.28rem 0.55rem; border: 1px dashed var(--line); border-radius: 3px;
|
| 88 |
+
color: var(--muted); transition: color 200ms ease, border-color 200ms ease, text-decoration-color 200ms ease;
|
| 89 |
+
text-decoration: line-through; text-decoration-color: transparent; text-decoration-thickness: 2px;
|
| 90 |
}
|
| 91 |
+
.fakes li.caught { color: var(--fail); border-color: rgba(244, 184, 96, 0.55); text-decoration-color: var(--fail); }
|
| 92 |
|
| 93 |
+
.ghost {
|
| 94 |
+
margin-top: 1.4rem; font: 500 0.9rem var(--sans); color: var(--paper); cursor: pointer;
|
| 95 |
+
background: none; border: 1px solid var(--line); border-radius: 3px; padding: 0.5rem 0.9rem;
|
| 96 |
}
|
| 97 |
+
.ghost:hover { border-color: var(--muted); }
|
| 98 |
|
| 99 |
+
/* Section blocks */
|
| 100 |
+
.block { padding: clamp(2.5rem, 5vw, 4rem) 0; border-top: 1px solid var(--line); }
|
| 101 |
+
.block-head { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); gap: 2rem; align-items: baseline; margin-bottom: 2rem; }
|
| 102 |
+
.block-head h2 { font-size: clamp(1.6rem, 2.6vw, 2.2rem); line-height: 1.1; }
|
| 103 |
+
.block-head p { color: var(--muted); max-width: 56ch; }
|
| 104 |
+
|
| 105 |
+
/* Funnel: a real sequence, so the steps are numbered */
|
| 106 |
+
.funnel-wrap { display: grid; grid-template-columns: minmax(0, 1fr) 260px; gap: 3rem; align-items: start; }
|
| 107 |
+
.funnel { list-style: none; margin: 0; padding: 0; counter-reset: step; }
|
| 108 |
+
.funnel li {
|
| 109 |
+
counter-increment: step; display: grid; grid-template-columns: 2rem minmax(0, 1fr); gap: 0.2rem 1rem;
|
| 110 |
+
padding: 0.85rem 0; border-bottom: 1px dashed var(--line);
|
| 111 |
+
}
|
| 112 |
+
.funnel li::before { content: counter(step); grid-row: span 2; font: 500 0.95rem var(--mono); color: var(--muted); padding-top: 0.1rem; }
|
| 113 |
+
.f-top { display: flex; justify-content: space-between; gap: 1rem; align-items: baseline; }
|
| 114 |
+
.f-label { font-weight: 700; }
|
| 115 |
+
.f-count { font: 500 1rem var(--mono); }
|
| 116 |
+
.f-bar { height: 10px; background: rgba(238, 243, 248, 0.07); border-radius: 2px; overflow: hidden; margin-top: 0.45rem; }
|
| 117 |
+
.f-bar span { display: block; height: 100%; background: var(--paper); }
|
| 118 |
+
.funnel li:last-child .f-bar span { background: var(--pass); }
|
| 119 |
+
.f-lost { grid-column: 2; font-size: 0.86rem; color: var(--fail); }
|
| 120 |
+
.f-lost.none { color: var(--muted); }
|
| 121 |
+
|
| 122 |
+
.ledger { border-left: 1px solid var(--line); padding-left: 1.5rem; }
|
| 123 |
+
.ledger dl { margin: 0; display: grid; gap: 1.1rem; }
|
| 124 |
+
.ledger dt { color: var(--muted); font-size: 0.86rem; }
|
| 125 |
+
.ledger dd { margin: 0.15rem 0 0; font: 500 1.15rem var(--mono); }
|
| 126 |
+
.ledger dd small { display: block; font: 400 0.8rem var(--sans); color: var(--muted); margin-top: 0.2rem; }
|
| 127 |
+
|
| 128 |
+
/* Coverage grid */
|
| 129 |
+
.coverage { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2rem 3rem; }
|
| 130 |
+
.cov-col { display: grid; grid-template-columns: minmax(0, 1fr) repeat(3, 56px); gap: 4px 6px; align-items: center; align-content: start; }
|
| 131 |
+
.cov-h { font-size: 0.78rem; color: var(--muted); text-align: center; }
|
| 132 |
+
.cov-t { font-size: 0.88rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-right: 0.5rem; }
|
| 133 |
+
.cov-c {
|
| 134 |
+
height: 22px; border: 1px solid var(--line); border-radius: 2px; display: grid; place-items: center;
|
| 135 |
+
font: 500 0.7rem var(--mono); color: var(--deep);
|
| 136 |
+
}
|
| 137 |
+
.cov-c.has { background: var(--pass); border-color: var(--pass); }
|
| 138 |
+
|
| 139 |
+
/* Rejections */
|
| 140 |
+
.rej-empty { color: var(--muted); max-width: 60ch; }
|
| 141 |
+
.rej-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.9rem; max-width: 820px; }
|
| 142 |
+
.rej-list li { display: grid; grid-template-columns: 3.5rem minmax(0, 1fr); gap: 1rem; align-items: baseline; }
|
| 143 |
+
.rej-n { font: 500 1.25rem var(--mono); color: var(--fail); text-align: right; }
|
| 144 |
+
.rej-why { font-weight: 700; }
|
| 145 |
+
.rej-desc { color: var(--muted); font-size: 0.92rem; }
|
| 146 |
+
|
| 147 |
+
/* Browser */
|
| 148 |
+
.browser { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 2rem; align-items: start; }
|
| 149 |
+
.filters { display: grid; gap: 0.7rem; margin-bottom: 1rem; }
|
| 150 |
+
.filters input {
|
| 151 |
+
width: 100%; font: 400 0.95rem var(--sans); color: var(--paper); background: var(--deep);
|
| 152 |
+
border: 1px solid var(--line); border-radius: 3px; padding: 0.55rem 0.7rem;
|
| 153 |
+
}
|
| 154 |
+
.filters input::placeholder { color: var(--muted); }
|
| 155 |
+
.seg { display: flex; border: 1px solid var(--line); border-radius: 3px; overflow: hidden; }
|
| 156 |
+
.seg button {
|
| 157 |
+
flex: 1; font: 500 0.85rem var(--sans); color: var(--muted); background: none; border: 0; padding: 0.45rem 0; cursor: pointer;
|
| 158 |
+
}
|
| 159 |
+
.seg button + button { border-left: 1px solid var(--line); }
|
| 160 |
+
.seg button[aria-checked="true"] { background: var(--paper); color: var(--deep); }
|
| 161 |
+
|
| 162 |
+
.plist { list-style: none; margin: 0; padding: 0; max-height: 640px; overflow-y: auto; border-top: 1px solid var(--line); }
|
| 163 |
+
.plist button {
|
| 164 |
+
display: block; width: 100%; text-align: left; background: none; border: 0; border-bottom: 1px solid var(--line);
|
| 165 |
+
color: var(--paper); padding: 0.75rem 0.4rem; cursor: pointer; font: inherit;
|
| 166 |
}
|
| 167 |
+
.plist button:hover { background: rgba(238, 243, 248, 0.04); }
|
| 168 |
+
.plist button[aria-current="true"] { background: rgba(142, 227, 184, 0.1); box-shadow: inset 3px 0 0 var(--pass); }
|
| 169 |
+
.p-title { display: block; font-weight: 700; font-size: 0.97rem; }
|
| 170 |
+
.p-meta { display: block; color: var(--muted); font-size: 0.82rem; margin-top: 0.1rem; }
|
| 171 |
+
.plist .none { padding: 1rem 0.4rem; color: var(--muted); }
|
| 172 |
+
|
| 173 |
+
.detail {
|
| 174 |
+
background: var(--deep); border: 1px solid var(--line); border-radius: 4px; padding: clamp(1.25rem, 3vw, 2rem); min-height: 400px;
|
| 175 |
+
}
|
| 176 |
+
.d-meta { color: var(--muted); font-size: 0.88rem; margin-bottom: 1.2rem; }
|
| 177 |
+
.prose { max-width: var(--measure); }
|
| 178 |
+
.prose h1, .prose h2, .prose h3 { font-weight: 700; letter-spacing: -0.015em; margin: 1.4em 0 0.5em; line-height: 1.2; }
|
| 179 |
+
.prose h1:first-child, .prose h2:first-child, .prose h3:first-child { margin-top: 0; }
|
| 180 |
+
.prose h1, .prose h2 { font-size: 1.45rem; }
|
| 181 |
+
.prose h3 { font-size: 1.1rem; }
|
| 182 |
+
.prose p, .prose ul, .prose ol { margin: 0 0 0.9em; }
|
| 183 |
+
.prose code { font-size: 0.86em; background: rgba(238, 243, 248, 0.07); padding: 0.1em 0.3em; border-radius: 2px; }
|
| 184 |
+
.prose pre code { background: none; padding: 0; }
|
| 185 |
+
pre {
|
| 186 |
+
margin: 0 0 1em; padding: 0.9rem 1rem; overflow-x: auto; font-size: 0.82rem; line-height: 1.55;
|
| 187 |
+
background: rgba(238, 243, 248, 0.05); border: 1px solid var(--line); border-radius: 3px;
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
.tabs { display: flex; gap: 1.4rem; margin-top: 2rem; border-bottom: 1px solid var(--line); }
|
| 191 |
+
.tabs button {
|
| 192 |
+
background: none; border: 0; color: var(--muted); font: 500 0.95rem var(--sans); padding: 0.6rem 0; cursor: pointer;
|
| 193 |
+
border-bottom: 2px solid transparent; margin-bottom: -1px;
|
| 194 |
+
}
|
| 195 |
+
.tabs button[aria-selected="true"] { color: var(--paper); border-bottom-color: var(--pass); }
|
| 196 |
+
.tabpanel { padding-top: 1.1rem; }
|
| 197 |
+
.tests { list-style: none; margin: 0; padding: 0; }
|
| 198 |
+
.tests li { font: 400 0.8rem/1.5 var(--mono); padding: 0.45rem 0 0.45rem 1.4rem; border-bottom: 1px dashed var(--line); position: relative; word-break: break-word; }
|
| 199 |
+
.tests li::before { content: ""; position: absolute; left: 0; top: 0.85rem; width: 8px; height: 8px; border-radius: 1px; background: var(--pass); }
|
| 200 |
+
|
| 201 |
+
/* highlight.js tokens in palette */
|
| 202 |
+
.hljs-keyword, .hljs-built_in { color: #a9c7ff; }
|
| 203 |
+
.hljs-string { color: var(--pass); }
|
| 204 |
+
.hljs-number, .hljs-literal { color: var(--fail); }
|
| 205 |
+
.hljs-comment { color: #6f86a8; font-style: italic; }
|
| 206 |
+
.hljs-title, .hljs-title.function_ { color: #ffffff; font-weight: 500; }
|
| 207 |
+
.hljs-params { color: var(--paper); }
|
| 208 |
+
|
| 209 |
+
.foot {
|
| 210 |
+
border-top: 1px solid var(--line); padding: 2rem clamp(1.25rem, 4vw, 3.5rem) 3rem; color: var(--muted); font-size: 0.88rem;
|
| 211 |
+
}
|
| 212 |
+
.foot p { max-width: 80ch; }
|
| 213 |
+
.foot a { color: var(--paper); }
|
| 214 |
+
|
| 215 |
+
.load-error { padding: 4rem 0; max-width: 60ch; }
|
| 216 |
|
| 217 |
+
@media (max-width: 960px) {
|
| 218 |
+
.hero, .block-head, .funnel-wrap, .browser, .coverage { grid-template-columns: minmax(0, 1fr); }
|
| 219 |
+
.ledger { border-left: 0; border-top: 1px solid var(--line); padding: 1.5rem 0 0; }
|
| 220 |
+
.ledger dl { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
|
| 221 |
+
.plist { max-height: 320px; }
|
|
|
|
| 222 |
}
|
| 223 |
|
| 224 |
+
@media (prefers-reduced-motion: reduce) {
|
| 225 |
+
*, *::before, *::after { transition: none !important; animation: none !important; }
|
| 226 |
}
|