import os
import time
import subprocess
import sys
import argparse
import time
from openai import OpenAI
def fetch_generator(statement, model, maxtokens):
APIKEY = os.environ.get('DEEPSEEK_API_KEY')
if not APIKEY:
raise Exception('需要设置 DEEPSEEK_API_KEY 环境变量')
client = OpenAI(
api_key=APIKEY,
base_url='https://api.deepseek.com')
start_time = time.time()
msgs = [{ 'role': 'user', 'content':
"""
请根据以下信息学竞赛题目生成数据生成器。只输出 gen.py 代码。
要求:
1. 解析题目中的输入格式、数据范围和子任务划分
2. 创建 data/ 目录并生成所有 .in 文件
3. 数据严格符合题目约束
4. 使用合理的数据梯度,包含边界情况
5. 数据文件名一定为 'data{编号}.in',编号不含前导零
6. 没有子任务的,数据文件直接放在 data/ 下;有子任务的,为每个子任务创建 subtask{编号}/ 目录,把数据文件移动到对应的子任务目录中
7. 数据点在 10 到 20 个内
8. 务必确保你给出的数据是正确的!先列出生成器的设计思路和待满足的所有约束条件,确认无误后再生成完整代码
输出只包含可以直接运行的 gen.py 的代码,无其他内容。
题目描述:""" + statement}]
resp = client.chat.completions.create(
model=model,
messages=msgs,
stream=False,
temperature=0.0,
max_tokens=maxtokens)
response = resp.choices[0].message.content
tokens = resp.usage.total_tokens
if response.startswith('```python'):
response = response[9:-3]
return (response, tokens, time.time() - start_time)
def execute(s):
print('正在执行命令:', s)
try:
subprocess.run(['bash', '-c', s], check=True, timeout=40)
except subprocess.CalledProcessError as e:
raise Exception('命令执行错误')
except subprocess.TimeoutExpired:
raise Exception('命令执行超时(20s)')
def generate_in():
# 其实应该用个沙盒比较安全,但是我懒得写了。可以最后扔到容器里头跑。
execute('python gen.py')
def flatten_data():
execute('find -type f | xargs -I {} mv -n {} . || true')
execute('rmdir subtask* || true')
def run_std():
if not os.path.exists('../std.cpp'):
raise Exception('未找到 std.cpp')
execute('g++ ../std.cpp -o std -Wall -Wextra -O2 -std=c++14')
for i in os.listdir():
if not i.endswith('.in'):
print(f'警告:未知文件 {i}')
continue
out = i[:-2] + 'ans'
execute(f'./std < {i} > {out}')
execute('rm std')
def gen_problem_conf(time, mem):
execute(f'python ../autoconf.py {time} {mem}')
def compress_data():
execute('zip ../data.zip -r .')
def cleanup():
os.chdir('..')
execute('rm -r data/')
def pretty_size(d):
if d < 1024:
return f'{d}'
if d < 1048576:
return f'{d/1024:.2f} KB'
return f'{d/1048576:.2f} MB'
if __name__ == '__main__':
start_time = time.time()
parser = argparse.ArgumentParser()
parser.add_argument('statement', help='题面文件')
parser.add_argument('--model', type=str, default='deepseek-reasoner', help='使用的模型(默认为 deepseek-reaonser,可以改为 deepseek-chat)')
parser.add_argument('--maxtokens', type=int, default=50000, help='token 上限(默认为 50000)')
parser.add_argument('--time', type=int, default=1, help='时间限制(秒,默认为 1)')
parser.add_argument('--mem', type=int, default=256, help='空间限制(MB,默认为 256)')
parser.add_argument('--offline', help='不生成新的 gen.py', action='store_true')
args = parser.parse_args()
if os.path.exists('data'):
print('正在清空已有的 data 目录')
execute('rm -r data')
if os.path.exists('data.zip'):
print('删除已存在的 data.zip')
execute('rm data.zip')
tokens = 0
with open(args.statement) as f:
if not args.offline:
print(f'正在请求 {args.model},token 上限为 {args.maxtokens} 个')
resp, tokens, duration = fetch_generator(f.read(), args.model, args.maxtokens)
with open('gen.py', 'w') as fw:
fw.write(resp)
print(f'--- tokens: {tokens}, time cost: {duration:.6f} seconds')
else:
if not os.path.exists('gen.py'):
raise Exception('离线模式下必须提供已有的 gen.py')
print('(离线模式)')
generate_in()
os.chdir('data')
gen_problem_conf(args.time, args.mem)
# run_std 需要一个扁平的目录,也就是所有文件放在 data/ 下,而 autoconf.py 不要求这么做
flatten_data()
run_std()
compress_data()
cleanup()
prettysize = pretty_size(os.path.getsize('data.zip'))
print(f'已生成 data.zip({prettysize}),耗时 {(time.time() - start_time):.2f} 秒,消耗 {tokens} 个 token')
WyOJ Datum
ryp
2026-01-03 17:36:34
Light away, it won't be long.
评论
暂无评论
发表评论
可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。

鲁ICP备2025150228号