{"challengeId":"costas-32","entry":"verifier.mjs","sha256":"9fa78e9b2a493c132ed7993c9fce70b23a92aa014a581625fcb910778b430198","scoreDirection":"maximize","scoreLabel":"order","seedPolicy":{"mode":"fixed","testCount":1},"source":"// Frozen verifier for costas-32. Self-contained (no imports, no external data).\n// The \"instance\" is a pure mathematical rule, fully specified right here: an\n// artifact is a Costas array of some order, and the score IS that order.\n//\n// A Costas array of order n is a permutation perm[] of 0..n-1 (perm[i] = the row\n// of the single dot in column i) such that the displacement vectors between every\n// PAIR of dots are all distinct. Equivalently, for each column-gap g in 1..n-1,\n// the differences { perm[i+g] - perm[i] } over all valid i are pairwise DISTINCT.\n//\n// Score = order = perm.length. Bigger order wins. Costas arrays are known for\n// many orders, but NONE is known for order 32 or 33 (open since the 1980s):\n// reaching order 32 would be a literal first-in-the-world object.\n//\n// Pure integer arithmetic on the scored quantity — deterministic; seedPolicy\n// \"fixed\". Worst case is the bound (order 64): the property check is O(order^2)\n// integer comparisons, far under timeoutMs.\n\nconst MAX_ORDER = 64; // hard bound on input size; worst case stays well under 4s.\n\nfunction gate(name, pass, detail) { return { name, pass, detail }; }\nfunction bad(name, detail) { return { ok: false, score: null, gates: [gate(name, false, detail)], behavior: {}, logs: [] }; }\n\nexport function verify(ctx) {\n  const sol = ctx && ctx.solution;\n  if (!sol || typeof sol !== 'object') return bad('structure', 'expected { perm: int[] }');\n  const perm = sol.perm;\n  if (!Array.isArray(perm)) return bad('structure', 'expected { perm: int[] }');\n  const n = perm.length;\n  if (n < 1) return bad('structure', 'perm must be non-empty');\n  if (n > MAX_ORDER) return bad('bound', `order ${n} exceeds bound ${MAX_ORDER}`);\n\n  // Permutation check: every entry an integer in 0..n-1, each used exactly once.\n  const seen = new Array(n).fill(false);\n  for (let i = 0; i < n; i++) {\n    const v = perm[i];\n    if (!Number.isInteger(v) || v < 0 || v >= n) {\n      return bad('permutation', `perm[${i}] must be an integer in 0..${n - 1}; got ${String(v)}`);\n    }\n    if (seen[v]) return bad('permutation', `value ${v} repeats; not a permutation`);\n    seen[v] = true;\n  }\n\n  // Costas property: for every column-gap g (1..n-1), the displacement\n  // differences { perm[i+g] - perm[i] } must be pairwise distinct. A repeated\n  // difference means two dot-pairs share the same displacement vector (g, d).\n  for (let g = 1; g < n; g++) {\n    const used = new Set();\n    for (let i = 0; i + g < n; i++) {\n      const d = perm[i + g] - perm[i];\n      if (used.has(d)) {\n        return bad('costas', `gap g=${g} has a repeated displacement difference d=${d} (columns share a vector)`);\n      }\n      used.add(d);\n    }\n  }\n\n  return {\n    ok: true,\n    score: n,\n    gates: [gate('valid-costas', true, `valid Costas array of order ${n}`)],\n    behavior: { order: n },\n    logs: [`order=${n}`],\n  };\n}\n"}