Files

50 lines
2.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { writeFileSync } from "node:fs";
import { pyDumps, readRun, type J } from "./py.ts";
// 任务书 15 第 4.3 节的材料:几次运行的全部最终入口(认领时)和第 1 轮提案,写成一个 items.json,交给 jevroutes.ts 问 Jev。
// 逐行移植对照材料里的 items.py,输出和 Python 的 json.dump(..., ensure_ascii=False, indent=0) 逐字节一致。
// node eval/route/items.ts <输出 items.json> <运行目录名>...
// 运行目录是 /home/iomgaa/inforsi-eval/<运行目录名>/study/ledger.sqlite,只读打开。
const [out, ...runs] = process.argv.slice(2);
if (out === undefined || runs.length === 0) throw new Error("用法:node eval/route/items.ts <输出 items.json> <运行目录名>...");
function* walk(o: J): Generator<string> {
if (typeof o === "string") yield o;
else if (Array.isArray(o)) for (const v of o) yield* walk(v);
else if (o !== null && typeof o === "object") for (const v of Object.values(o)) yield* walk(v);
}
const count = (s: string, sub: string) => s.split(sub).length - 1;
const items: Array<Record<string, string>> = [];
for (const run of runs) {
const rows = readRun(run);
// 最终入口:第一条认领调用的记录里,入口全文最多的那段文字,按"### 入口 e-"切开。
for (const [k, c] of rows) {
if (k !== "callStarted" || !pyDumps(c, false).includes("r0-claim")) continue;
let txt = "";
let best = -1;
for (const s of walk(c)) {
const n = count(s, "### 入口 e-");
if (n > best) [txt, best] = [s, n];
}
for (const p of txt.split(/\n(?=### 入口 e-)/).slice(1)) {
const m = /^### 入口 (e-researcher-\d-\d+):(.*?)(作者 (researcher-\d))\n([\s\S]*)/.exec(p);
if (m === null) throw new Error(`${run} 的认领材料里有一段入口对不上格式:${p.slice(0, 80)}`);
const body = m[4]!.split("\n## ")[0]!.trim();
items.push({ run, id: m[1]!, kind: "entry", name: m[2]!, author: m[3]!, text: body });
}
break;
}
for (const [k, c] of rows) {
if (k !== "submission" || c.kind !== "proposal") continue;
const cc = c.content;
const t = cc.body + "\n\n因子:\n" + cc.factors.map((f: J) => `- ${f.name}:${f.method}`).join("\n");
items.push({ run, id: c.item, kind: "proposal", name: cc.body.split("\n")[0].replace(/^[# ]+/, ""), author: c.author, text: t });
}
}
const indent0 = (o: Record<string, string>) => "{\n" + Object.entries(o).map(([k, v]) => `${pyDumps(k, false)}: ${pyDumps(v, false)}`).join(",\n") + "\n}";
writeFileSync(out, "[\n" + items.map(indent0).join(",\n") + "\n]");
console.log(items.length);
items.forEach((x, i) => console.log(i, x["run"]!.slice(11), x["id"], [...x["text"]!].length, [...x["name"]!].slice(0, 70).join("")));