2026年了,怎么在 Hydro 配置通信题?

测试功能,可能还有大量问题。

2026年了,怎么在 Hydro 配置通信题?

我们注意到 Hydro 题目中有这个选项:

好的怎么用呢?

我们发现,没有任何文档指出这个类型该怎么配置。

但在 Hydro 的 Github 仓库上,我们找到了一份代码:

import { NormalizedCase, STATUS } from '@hydrooj/common';
import { runFlow } from '../flow';
import { Parameter, runPiped } from '../sandbox';
import signals from '../signals';
import { Context, ContextSubTask } from './interface';

function judgeCase(c: NormalizedCase) {
    return async (ctx: Context, ctxSubtask: ContextSubTask) => {
        const { address_space_limit, process_limit } = ctx.session.getLang(ctx.lang);
        let managerArgs = '';
        const execute: Parameter[] = [{
            execute: ctx.executeManager.execute,
            stdin: c.input ? { src: c.input } : { content: '' },
            copyIn: ctx.executeManager.copyIn,
            time: c.time * 2,
            memory: c.memory * 2,
            env: { ...ctx.env, HYDRO_TESTCASE: c.id.toString() },
        }];
        const pipeMapping = [];
        for (let i = 0; i < ctx.config.num_processes; i++) {
            managerArgs += ` /proc/self/fd/${i * 2 + 3} /proc/self/fd/${i * 2 + 4}`;
            execute.push({
                execute: `${ctx.executeUser.execute} ${i}`,
                copyIn: ctx.executeUser.copyIn,
                time: c.time,
                memory: c.memory,
                addressSpaceLimit: address_space_limit,
                processLimit: process_limit,
            });
            pipeMapping.push({
                name: `sol2mgr[${i}]`,
                in: { index: i + 1, fd: 1 },
                out: { index: 0, fd: i * 2 + 3 },
            });
            pipeMapping.push({
                name: `mgr2sol[${i}]`,
                in: { index: 0, fd: i * 2 + 4 },
                out: { index: i + 1, fd: 0 },
            });
        }
        execute[0].execute += managerArgs;
        const res = await runPiped(execute, pipeMapping);
        const resManager = res[0];
        let time = 0;
        let memory = 0;
        let score = 0;
        let status = STATUS.STATUS_ACCEPTED;
        let message: any;
        for (let i = 0; i < ctx.config.num_processes; i++) {
            const result = res[i + 1];
            time += result.time;
            memory = Math.max(memory, result.memory);
            if (result.time > c.time) status = STATUS.STATUS_TIME_LIMIT_EXCEEDED;
            else if (result.memory > c.memory * 1024) status = STATUS.STATUS_MEMORY_LIMIT_EXCEEDED;
            else if ((result.code && result.code !== 13 /* Broken Pipe */) || (result.code === 13 && !resManager.code)) {
                status = STATUS.STATUS_RUNTIME_ERROR;
                if (ctx.config.detail === 'full') {
                    if (result.code < 32 && result.signalled) message = signals[result.code];
                    else message = { message: 'Your program returned {0}.', params: [result.code] };
                }
            }
        }
        if (status === STATUS.STATUS_ACCEPTED) {
            score = Math.floor(c.score * (+resManager.stdout || 0));
            status = score === c.score ? STATUS.STATUS_ACCEPTED : STATUS.STATUS_WRONG_ANSWER;
            message = resManager.stderr;
            if (resManager.code) message += ` (Manager exited with code ${resManager.code})`;
        }
        return {
            id: c.id,
            subtaskId: ctxSubtask.subtask.id,
            status,
            score,
            time,
            memory,
            message,
        };
    };
}

export const judge = async (ctx: Context) => await runFlow(ctx, {
    compile: async () => {
        [ctx.executeUser, ctx.executeManager] = await Promise.all([
            ctx.compile(ctx.lang, ctx.code),
            ctx.compileLocalFile('manager', ctx.config.manager),
        ]);
    },
    judgeCase,
});

这便是唯一有关通信题配置的了。

当然很可能看不懂(我也看不懂),但在使用 AI 工具分析后,就知道 Hydro 如何评测通信题了:

  1. 你需要实现一个 manager,功能是管理通信和评分。
  2. Hydro 会将选手代码在 num_processes 个进程里独立运行,同时创建 num_processes*2 个管道,第 \(i\) 个进程的输入被重定向到管道 \(2i+4\),输出被重定向到是 \(2i+3\)
  3. Manager 可以使用管道与进程 IO 通信,最后输出 \([0,1]\) 间的实数表示分数,stderr 将输出评分信息,stdin 读入数据。

接下来便有思路了。

posted @ 2026-04-16 19:35  ThisIsLu  阅读(7)  评论(0)    收藏  举报