npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

atcoderjs

v0.1.8

Published

TypeScript utilities for AtCoder

Readme

AtcoderJS

AtCoder 用の JavaScript ライブラリです。

npm install atcoderjs
import { 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.txt

Node.js 向けに bundle する場合:

bun build --target node c.ts --outdir output --minify
node output/c.js < input.txt

esbuild を使う場合:

npx esbuild c.ts --bundle --platform=node --format=esm --outfile=output/c.js --minify
node output/c.js < input.txt

Deno で bundle する場合:

deno bundle -o output/c.js c.ts
deno run output/c.js < input.txt

Deno の 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_M
import { 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 つの意味として読みたいときは tupleobject を使います。

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 check

src/ は実行時ライブラリそのものではなく、Babel で dist/ を生成するための codegen です。公開パッケージには生成済みの dist/ と型定義が入ります。