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 🙏

© 2025 – Pkg Stats / Ryan Hefner

genesis-kit

v1.2.0

Published

Simple and easy-to-use test data generator and comparator designed for algorithm competitions (OI/ACM).

Readme

English Version

Genesis: 为算法竞赛而生的测试数据生成器

npm version License

Genesis 是一个为算法竞赛出题人、选手和教练量身打造的、极其简单易用的测试数据生成工具。它将繁琐的编译、数据生成、文件 I/O、对拍验证等流程自动化,让你能专注于数据本身的设计,而非过程的实现。

✨ 核心特性

  • 声明式 API: 使用链式调用 .case().run() 直观地定义数据和对拍,代码结构与逻辑高度一致。
  • 内置对拍器 (Checker): 自动运行标程和待测程序,高保真地对比输出 (Diff),快速定位 WA/TLE
  • 强大的数据生成器 (G): 内置丰富、便捷的生成函数 (G.int, G.permutation, G.matrix, G.even, G.tree, G.graph 等),满足 99% 的基础数据需求。
  • 智能格式化: 你只需返回结构化的数据(如 [[n, m], grid]),Genesis 会自动处理空格和换行,生成符合要求的 .in 文件。无论 grid 是数字矩阵还是字符串数组,它都能正确处理!
  • 多语言支持: 原生支持 C++, Go, Rust, Java, Python, Node.js 等多种语言。只需提供源文件,Genesis 会自动处理编译和执行。
  • 自动编译与缓存: 自动探测所需编译器(g++, go, rustc 等),并对标程和解法进行编译。基于文件内容和编译参数的智能缓存机制,源码不变则无需重复编译,极大提升效率。
  • 高性能: 利用 Node.js 的异步特性和多核心 CPU,Maker 可并行生成所有测试用例,Checker 可高速执行对拍。
  • CLI 工具: 提供便捷的命令行工具,支持项目初始化、数据生成、对拍验证和清理等操作。
  • 跨平台: 在 Windows (MSYS2/MinGW)、macOS 和 Linux 上均可无缝工作。

🚀 快速上手 (Maker 篇)

CLI 工具

Genesis 提供了便捷的命令行工具,支持以下操作:

# 初始化一个 C++ 项目 (默认)
genesis init

# 初始化一个 Go 语言项目
genesis init --lang go

# 生成数据
genesis make

# 运行对拍
genesis check

# 清理生成的文件
genesis clean

1. 安装

确保你已经安装了 Node.js (v16+) 和 Bun (或 tsx 用于执行 TypeScript)。

在你的项目目录下,将 Genesis 添加到开发依赖:

bun add genesis-kit --dev
# 或者使用 npm / yarn / pnpm
# npm install genesis-kit --save-dev

2. 编写你的第一个 make.ts

以 Go 语言为例,假设你的项目结构如下:

.
├── std.go         # 你的 Go 标程
└── make.ts        # 你的数据生成脚本

现在,编写 make.ts 来生成 A+B Problem 的数据:

// make.ts
import { Maker, G } from 'genesis-kit';

// 即使标程是 Go, 数据生成脚本的语法也完全一样
Maker
  .configure({
    solution: 'std.go' // 告诉 Maker 你的标程是哪个文件
  })
  // Case 1: 小数据
  .case('Small Numbers', () => {
    const a = G.int(1, 100);
    const b = G.int(1, 100);
    return [[a, b]]; // -> 会被格式化为 "a b"
  })

  // Case 2-6: 批量生成 5 个随机中等数据
  .cases(5, () => {
    const a = G.int(1000, 100000);
    const b = G.int(1000, 100000);
    return [[a, b]];
  })

  // Case 7: 极限数据
  .case('Max Numbers', () => {
    const a = 1_000_000_000;
    const b = 1_000_000_000;
    return [[a, b]];
  })

  // 启动生成流程!
  .generate();

3. 运行

打开终端,执行:

bun make.ts
# 或者
tsx make.ts

发生了什么? Genesis 会自动识别出 std.go 是一个 Go 程序,找到并调用 go 编译器进行编译,然后并行执行 7 个 case,最后将输入 (.in) 和输出 (.out) 保存到 data/ 目录中。

📚 API 参考

Genesis 提供了两大核心工具:Maker (用于批量生成数据) 和 Checker (用于对拍验证)。


Checker (对拍器) API

Checker 是一个自动化的“对拍”工具。它使用同一个数据生成器,分别运行“标准答案”(std) 和“待测解法”(target),并高保真地对比它们的输出,直到找到第一个错误 (WA / TLE / RE) 为止。

快速上手:check.ts

让我们用 Checker 来对拍一个 Python 程序。

准备文件:

  1. std.py (A+B, 正确)
  2. my_buggy.py (A+B, 有 bug, 未处理大数)

编写 check.ts:

// check.ts
import { Checker, G } from 'genesis-kit';

Checker
  // 1. 配置
  .configure({
    std: 'std.py',          // (必需) 标程,必须正确
    target: 'my_buggy.py',  // (必需) 你要测试的程序
    
    // (可选) 对比模式
    // 'normalized' (默认): 模拟 OJ 裁决 (忽略行尾空格、忽略空行)
    // 'exact': 严格字节对比
    compareMode: 'normalized'
  })

  // 2. 定义数据生成器
  .gen(() => {
    // 90% 的几率生成 int 安全范围内的数
    if (Math.random() < 0.9) {
      return [[G.int(1e9), G.int(1e9)]];
    }
    // 10% 的几率生成 HACK 数据 (会导致 int 溢出)
    return [[G.int(1.5e9, 2e9), G.int(1.5e9, 2e9)]];
  })

  // 3. (可选) 设置超时
  .timeout(2000) // 仅对 target 生效,单位毫秒

  // 4. 运行
  .run(10000); // 运行 10000 次,或在第一次出错时停止

.run() 流程

.run(N) 启动时, Checker 会:

  1. 准备执行:自动为 stdtarget 准备执行环境。如果是 C++, Go, Rust 等编译型语言,则会自动编译并缓存。
  2. 循环:开始一个串行循环,最多 N 次。
  3. 生成:在每次循环中,调用 .gen() 里的函数生成一组新数据。
  4. 执行:将生成的数据作为 stdin,分别运行 stdtarget 程序。
  5. 裁决
    • TLE / RE:如果 target 超时或崩溃 (RE),立即停止。
    • WA (Wrong Answer):调用高保真对比器 (Diff) 比较 stdtargetstdout
  6. 报告
    • PASSED:在控制台更新计数,继续下一次循环。
    • FAILED (WA/TLE/RE)立即停止,并在控制台打印详细的失败报告(包括输入、标程输出、你的输出)。
    • 保存现场:自动将导致失败的数据保存到:
      • _checker_fail.in
      • _checker_std.out
      • _checker_my.out

Maker (数据生成器) API

MakerGenesis 的批量数据生成工具。整个流程的核心是定义一系列的测试用例(Test Cases),然后启动生成。

定义测试点: .case().cases()

这是 Genesis 最核心的两个方法,用于定义你想要生成的测试数据。

.case(): 创建一个独立的测试点

每次调用 .case() 都会向生成队列中添加一个测试任务。最终,这会生成一组对应的输入/输出文件(例如 1.in1.out)。

你提供的生成器函数 generator 的返回值,构成了这一个 .in 文件的全部内容

// 语法
.case(label: string, generator: () => any) // 带标签,用于在日志中区分
.case(generator: () => any)                // 匿名

// 示例
Maker
  .case('Sample 1', () => { /* ... */ }) // -> 将生成 1.in / 1.out
  .case('Edge Case', () => { /* ... */ }) // -> 将生成 2.in / 2.out
.cases(): 批量创建多个相似的测试点

.cases(N, generator) 是一个便捷的 API,它等同于将同一个 generator 调用 N 次的 .case()

这会向队列中添加 N 个独立的测试任务,最终生成 N 组文件(例如从 3.in/3.out 一直到 7.in/7.out)。

生成器函数 generator 会被独立执行 N 次,每次的执行结果都将用于创建一个全新的 .in 文件,确保了数据的随机性和多样性。

// 语法
.cases(count: number, generator: () => any)

// 示例
Maker
  .case('Sample', () => { /* ... */ })       // -> 生成 1.in / 1.out
  .cases(5, () => {
    // 这个函数会被独立执行 5 次
    const a = G.int(1, 100);
    const b = G.int(1, 100);
    return [[a, b]];
  })                                       // -> 依次生成 2.in/out, 3.in/out, 4.in/out, 5.in/out, 6.in/out

配置与启动

.configure(config: GenesisConfig)

在调用链的任意位置(通常是开头)使用,用于对 Genesis 的默认行为进行配置。这是一个可选步骤。

Maker.configure({
  solution: 'main.go',    // 指定标程文件名
  outputDir: 'testdata',  // 指定输出目录 (默认: 'data')
  compiler: 'g++-12',     // 为编译型语言手动指定编译器 (默认: 自动探测)
  startFrom: 1,           // 文件编号起始值 (默认: 1)
});
.generate(): Promise<void>

必须在 Maker 链式调用的末尾调用。它会启动整个自动化流程:编译、生成、运行标程、保存文件。


G (Generator) API

G 对象提供了一系列开箱即用的数据生成函数。

数字 (Numbers)

| 函数 | 描述 | 示例 | | --------------------- | ---------------------------------------------- | ------------------------------------- | | G.int(min, max) | 生成 [min, max] 内的随机整数。 | G.int(1, 10) -> 7 | | G.ints(count, min, max) | 生成 count[min, max] 内的整数数组。 | G.ints(3, 1, 10) -> [2, 9, 4] | | G.even(min, max) | 生成 [min, max] 内的随机偶数。 | G.even(1, 10) -> 6 | | G.odd(min, max) | 生成 [min, max] 内的随机奇数。 | G.odd(1, 10) -> 3 | | G.float(min, max, prec) | 生成 [min, max] 内带 prec 位小数的浮点数。 | G.float(0, 1, 2) -> 0.42 |

字符串 (Strings)

| 函数 | 描述 | 示例 | | ------------------------ | ---------------------------------- | ---------------------------------------- | | G.string(len, charset) | 生成指定长度和字符集的字符串。 | G.string(5, 'abc') -> "bacaa" | | G.word(min, max) | 生成 [min, max] 长度的小写单词。 | G.word(3, 5) -> "hello" | | G.words(count, min, max) | 生成 count 个随机单词数组。 | G.words(2, 3, 5) -> ["world", "cup"] |

数组与结构 (Arrays & Structures)

| 函数 | 描述 | 示例 | | ----------------------------- | -------------------------------------------------- | ------------------------------------------ | | G.array(count, fn) | 生成 count 个元素的数组,元素由 fn(i) 生成。 | G.array(3, i => i*i) -> [0, 1, 4] | | G.matrix(r, c, fn) | 生成 rxc 矩阵,单元格由 fn(i, j) 生成。 | G.matrix(2,2,() => 0) -> [[0,0],[0,0]] | | G.permutation(n, oneBased?) | 生成 n 的全排列 (默认从 1 开始)。 | G.permutation(3) -> [2, 1, 3] | | G.shuffle(arr) | 随机打乱数组(返回新数组)。 | G.shuffle([1,2,3]) -> [3, 1, 2] | | G.sample(arr, k) | 从数组中不重复地抽取 k 个元素。 | G.sample(['a','b','c'], 2) -> ['c', 'a'] |

树与图 (Trees & Graphs)

| 函数 | 描述 | 示例 | | ----------------------------- | -------------------------------------------------- | ------------------------------------------ | | G.tree(n, options?) | 生成 n 个顶点的树结构。支持路径、星形、随机等类型。 | G.tree(5) -> [[1,2],[2,3],[3,4],[4,5]] | | G.graph(n, m, options?) | 生成 n 个顶点、m 条边的图。支持连通性、权重、方向等配置。 | G.graph(5, 7, {connected: true}) -> 边列表 |

日期 (Dates)

| 函数 | 描述 | 示例 | | --------------------- | -------------------------------- | --------------------------------------------- | | G.isLeap(year) | 判断是否为闰年。 | G.isLeap(2000) -> true | | G.date(options) | 生成格式化的随机日期字符串。 | G.date({format: 'YYYY/MM/DD'}) -> "2025/10/14" |

🧠 智能格式化:所见即所得

我们坚信,出题人应该专注于数据逻辑,而不是输出格式。因此,MakerCheckergenerator 函数返回值 API 被设计得极其直观,遵循“所见即所得”的哲学。

你只需要返回一个数组,其结构就是你想要的 .in 文件的“蓝图”

核心规则:

  1. 一维数组或单个值 ([n, m], 100) -> 单行 (元素间用空格隔开)。
  2. 二维数组/矩阵 ([[1,0], [0,1]]) -> 多行 (自动格式化每一行)。
  3. 一维字符串数组 (['.##.', '..#.']) -> 多行 (每个字符串为独立一行)。

示例:两种最常用的 Grid 格式,现在都支持!

// --- 方式一: 直接返回数字矩阵 (推荐,更简洁) ---
.case('Number Matrix', () => {
  const n = 3, m = 4;
  // G.matrix 返回一个数字矩阵,例如 [[0,1,0,1], [1,...], ...]
  const grid = G.matrix(n, m, () => G.int(0, 1));

  // 直接返回!Genesis 会智能地将 grid 矩阵的每一行格式化。
  return [
    [n, m], // -> "3 4"
    grid    // -> "0 1 0 1\n1 1 0 0\n0 0 1 1"
  ];
})

// --- 方式二: 返回字符串数组 (同样支持) ---
.case('String Array', () => {
    const n = 2, m = 5;
    // 手动将 grid 的每一行处理成字符串
    const grid = G.matrix(n, m, () => G.sample(['.', '#'], 1)[0])
                 .map(row => row.join('')); // grid -> ['.##.#', '#..##']

    return [
        [n, m], // -> "2 5"
        grid    // -> ".##.#\n#..##"
    ];
})

这个强大而简单的模型覆盖了绝大多数竞赛题目的输入格式,让你能够以最自然的方式思考和编写代码。

🤝 贡献

欢迎提交 PR 和 Issue!如果你有新的生成器函数建议,或者发现了任何 Bug,请不要犹豫,在 GitHub 上告诉我们。

📜 开源许可

本项目基于 MIT License 开源。