Something went wrong. Try again.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475// Shrinks a failing input while TypeScript still parses it cleanly and the judge still fails it the same way.// Usage: node minimize.mjs file [kind] kind: threw (default) | chunked | ast | errors// Deletes line ranges, then token-ish character runs (ddmin style) and prints the result as a JSON string.import fs from "node:fs";import { createRequire } from "node:module";const root = new URL("../..", import.meta.url).pathname.replace(/\/$/, "");const ts = createRequire(root + "/package.json")("typescript");process.env.TYPESTRIP_ERASE_WASM ??= "build/erase.wasm";const { blankSourceFile } = await import(root + "/vendor/ts-blank-space/out/index.js");const { transformSync } = await import(root + "/src/index.js");
const kind = process.argv[3] ?? "threw";const SK = ts.SyntaxKind;
function jsAst(code) { const sf = ts.createSourceFile("out.js", code, ts.ScriptTarget.ESNext, false, ts.ScriptKind.JS); const out = []; (function visit(n) { if (n.kind === SK.EmptyStatement || n.kind === SK.SemicolonClassElement) return; out.push(n.kind); if (ts.isIdentifier(n) || ts.isPrivateIdentifier(n) || ts.isLiteralExpression(n)) out.push(JSON.stringify(n.text)); ts.forEachChild(n, visit); out.push(-1); })(sf); return out.join(",");}
function* parts(src, n) { for (let i = 0; i < src.length; i += n) yield src.slice(i, i + n);}function chunks(src, n) { let out = ""; for (const piece of transformSync(parts(src, n))) out += piece; return out;}
function fails(src) { const sf = ts.createSourceFile("input.ts", src, ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS); if (sf.parseDiagnostics.length) return false; const we = []; let want; try { want = blankSourceFile(sf, (n) => we.push(n.getStart(sf))); } catch { return false; } const ge = []; let got; try { got = transformSync(src, { onError: (e) => ge.push(e.start) }); } catch { return kind === "threw"; } if (kind === "threw") return false; if (kind === "ast") return jsAst(want) !== jsAst(got); if (kind === "errors") return jsAst(want) === jsAst(got) && we.join() !== ge.join(); for (const n of [1, 2, 3, 5, 7, 16]) { try { if (chunks(src, n) !== got) return true; } catch { return true; } } return false;}
let src = fs.readFileSync(process.argv[2], "utf8");if (!fails(src)) { console.log("input does not fail as", kind); process.exit(1); }
function shrink(parts, join) { let n = 2; while (parts.length >= 2) { const size = Math.ceil(parts.length / n); let reduced = false; for (let i = 0; i < parts.length; i += size) { const cand = parts.slice(0, i).concat(parts.slice(i + size)); if (fails(cand.join(join))) { parts = cand; n = Math.max(n - 1, 2); reduced = true; break; } } if (!reduced) { if (n >= parts.length) break; n = Math.min(n * 2, parts.length); } } return parts;}
src = shrink(src.split("\n"), "\n").join("\n");src = shrink(src.match(/\s+|\w+|./gs) ?? [], "").join("");console.log(JSON.stringify(src));