atcoderjs
v0.1.8
Published
TypeScript utilities for AtCoder
Readme
AtcoderJS
AtCoder 用の JavaScript ライブラリです。
npm install atcoderjsimport { createScanner, readInput, types } from "atcoderjs";
const scanner = createScanner(readInput());
const n = scanner.next(types.number);
const a = scanner.next(types.numbers(n));提出用に bundle する
readInput() は標準入力を読むため、browser target では動きません。
提出用に 1 ファイルへまとめる場合は、実行する runtime に合わせて bundle します。
Bun で bundle して Bun で実行する場合:
bun build --target bun c.ts --outdir output --minify
bun run output/c.js < input.txtNode.js 向けに bundle する場合:
bun build --target node c.ts --outdir output --minify
node output/c.js < input.txtesbuild を使う場合:
npx esbuild c.ts --bundle --platform=node --format=esm --outfile=output/c.js --minify
node output/c.js < input.txtDeno で bundle する場合:
deno bundle -o output/c.js c.ts
deno run output/c.js < input.txtDeno の deno bundle は experimental で、Deno 2.4.0 以降が必要です。
詳細は Deno 公式の bundling docs を確認してください:
https://docs.deno.com/runtime/reference/bundling/
| 入力 | 書き方 | 型 |
| --- | --- | --- |
| 整数 1 個 | scanner.next(types.number) | number |
| 文字列 1 個 | scanner.next(types.string) | string |
| BigInt 1 個 | scanner.next(types.bigint) | bigint |
| 数字を n 個 | scanner.next(types.numbers(n)) | number[] |
| 1 行の数字全部 | scanner.next(types.numbers()) | number[] |
| 文字を w 個 | scanner.next(types.chars(w)) | string[] |
| h x w の文字盤面 | scanner.next(types.grid(h, w)) | string[][] |
| 空白込みの 1 行 | scanner.next(types.line) | string |
| 同じ構造を m 個 | scanner.next(types.array(type, m)) | T[] |
| m 行読む | scanner.nexts(type, m) | T[] |
リテラルの長さは型にも反映されます。
const row = scanner.next(types.numbers(2));
// [number, number]
const edges = scanner.nexts(types.numbers(2), 3);
// [[number, number], [number, number], [number, number]]例: A != B かつ B = C
問題文:
整数 A, B, C が与えられます。A != B かつ B = C であるならば Yes を、 そうでないならば No を出力してください。
入力:
A B C提出例:
import { createScanner, readInput, types } from "atcoderjs";
const scanner = createScanner(readInput());
const [A, B, C] = scanner.next(types.numbers(3));
console.log(A !== B && B === C ? "Yes" : "No");例: 辺を読む
N 頂点 M 辺の無向グラフで、辺が M 行与えられる形です。
N M
u_1 v_1
u_2 v_2
...
u_M v_Mimport { createScanner, readInput, types } from "atcoderjs";
const scanner = createScanner(readInput());
const [N, M] = scanner.next(types.numbers(2));
const edges = scanner.nexts(types.numbers(2), M);
const graph = Array.from({ length: N }, () => []);
for (const [u, v] of edges) {
const a = u - 1;
const b = v - 1;
graph[a].push(b);
graph[b].push(a);
}例: 盤面を読む
H W
S_1
S_2
...
S_H各 S_i は長さ W の文字列です。例えば . と # からなる盤面で、
# の個数を数えるならこう書けます。
import { createScanner, readInput, types } from "atcoderjs";
const scanner = createScanner(readInput());
const [H, W] = scanner.next(types.numbers(2));
const grid = scanner.next(types.grid(H, W));
let count = 0;
for (let i = 0; i < H; i++) {
for (let j = 0; j < W; j++) {
if (grid[i][j] === "#") count++;
}
}
console.log(count);構造を作る
複数の値を 1 つの意味として読みたいときは tuple か object を使います。
const edge = types.tuple(types.number, types.number);
const edges = scanner.next(types.array(edge, M));名前付きで読みたいなら object です。
const item = scanner.next(types.object({
id: types.number,
name: types.string,
scores: types.numbers(3),
}));custom
変換や特殊な読み方は types.custom() に寄せます。
map のような別 API は用意していません。
const zeroIndexed = types.custom((read) => read.number() - 1);
const v = scanner.next(zeroIndexed);辺を 0-indexed にして読みたい場合:
const edge = types.custom((read) => [
read.number() - 1,
read.number() - 1,
]);
const edges = scanner.nexts(edge, M);少し複雑な構造も custom にまとめられます。
const point = types.custom((read) => ({
x: read.number(),
y: read.number(),
}));
const points = scanner.next(types.array(point, N));数値の表
数値の H x W 行列は専用 API を増やさず、既存の組み合わせで読みます。
const table = scanner.next(types.array(types.numbers(W), H));interactive
通常の問題では readInput() を使います。
interactive 問題ではまとめ読みできないので、createInteractiveIO(stdio) を使います。
import { createInteractiveIO, stdio, types } from "atcoderjs";
const io = createInteractiveIO(stdio);
const n = io.next(types.number);
io.writeLine(1);
const response = io.next(types.number);interactive では EOF まで待つ読み方を避けてください。
例えば io.nexts(types.number) のような長さなし読みは使わず、
必要な回数を明示します。
開発
pnpm install
pnpm run setup:githooks
pnpm run checksrc/ は実行時ライブラリそのものではなく、Babel で dist/ を生成するための
codegen です。公開パッケージには生成済みの dist/ と型定義が入ります。
