UNPKG

un-oj

Version:

Unified Online Judge information collector.

72 lines (70 loc) 2.42 kB
import { NotFoundError, Platform, UnOJError, parseMemory, parseTime } from "../platform-BncnsqE0.js"; import { FetchError } from "ofetch"; import { load } from "cheerio"; //#region src/platforms/atcoder.ts const DEFAULT_BASE_URL = "https://atcoder.jp"; /** * AtCoder platform. * * I18n is supported. */ var AtCoder = class extends Platform { constructor(options) { super(options, DEFAULT_BASE_URL, "en"); } /** * Fetches a problem from AtCoder, extracting information from HTML. */ async getProblem(id) { const contest = id.split("_")[0]; const path = `/contests/${contest}/tasks/${id}`; const url = new URL(path, this.baseURL).href; let $; try { $ = load(await this.ofetch(path, { responseType: "text" })); } catch (e) { if (e instanceof FetchError && e.statusCode === 404) throw new NotFoundError("problem"); throw new UnOJError(`Failed to fetch problem ${id}`, { cause: e }); } const statement = $("#task-statement"); if (!statement.length) throw new NotFoundError("problem"); const title = $(".h2").first().text().trimStart().split("\n")[0].split(" - ")[1]; const descContainer = statement.find(`span.lang-${this.locale}`); const hr = descContainer.find("hr").first(); if (hr.length) { hr.nextAll().remove(); hr.remove(); } const description = descContainer.html()?.trim(); if (!description) throw new NotFoundError("statement"); const limitsText = statement.prev("p").text(); const tlMatch = limitsText.match(/Time Limit: (\w+ \w+)/); const mlMatch = limitsText.match(/Memory Limit: (\w+ \w+)/); const type = description.includes("This is an interactive task.") || description.includes("これはインタラクティブな問題です") ? "interactive" : "traditional"; const samples = []; if (type === "traditional") statement.find(`span.lang-${this.locale} .part`).each((_, part) => { const h3 = $(part).find("h3").text(); if (h3.startsWith("Sample Input")) samples.push({ input: $(part).find("pre").text(), output: "" }); else if (h3.startsWith("Sample Output")) { if (samples.length) samples.at(-1).output = $(part).find("pre").text(); } }); return { id, type, title, link: url, description, samples, timeLimit: parseTime(tlMatch[1]), memoryLimit: parseMemory(mlMatch[1]), difficulty: void 0, tags: void 0 }; } }; //#endregion export { DEFAULT_BASE_URL, AtCoder as default };