最近苦于 stdio 交互题的对拍,发现网上没有多少相关的文章。我自己处理的方法是把 stdio 交互题改造为函数式交互题。虽然解决了问题,但是还是比较繁琐。
在此之后,我看到了一篇文章 交互题本机评测器 - Sshwy's Notes,这是在 linux 下的实现,虽然可以解决问题,但是还是不能在 Windows 下方便地使用。
但是它使用管道通信的方法给了我很大的启发,而 python 的 subprocess 模块提供了一种多平台管道通信的实现方法。
下面是我用 python 的 subprocess 模块实现的 stdio 交互题对拍器:
import sys
import subprocess
from threading import Thread, Lock
stop = False
def judger(argv):
if len(argv) != 3:
print(f"Usage: {argv[0]} [command1] [command2]", file=sys.stderr)
return 1
command1 = argv[1]
command2 = argv[2]
def run_command(name, p1, p2):
global stop
while True:
lock = Lock()
lock.acquire()
line = p1.stdout.readline()
if not line or stop:
stop = True
lock.release()
break
print(name + ": " + line.decode(), end="")
p2.stdin.write(line)
p2.stdin.flush()
lock.release()
p1 = subprocess.Popen(command1, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
p2 = subprocess.Popen(command2, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
t1 = Thread(target=run_command, args=(command1, p1, p2))
t2 = Thread(target=run_command, args=(command2, p2, p1))
t1.start()
t2.start()
p1.wait()
p2.wait()
return 0
if __name__ == "__main__":
sys.exit(judger(sys.argv))
使用方法:
$ cd demo
$ g++ ./problem.cpp -o ./problem
$ g++ ./grader.cpp -o ./grader
$ python ../interactive.py ./problem ./grader
./grader: 514
./problem: ? 258
./grader: 0
./problem: ? 129
./grader: 0
./problem: ? 65
./grader: 1
./problem: ? 97
./grader: 1
./problem: ? 113
./grader: 1
./problem: ? 121
./grader: 0
./problem: ? 117
./grader: 0
./problem: ? 115
./grader: 0
./problem: ? 114
./grader: 1
./problem: ! 114
AC
$
在 Github 上的链接:Github。
本文作者:ZnPdCo
本文链接: https://znpdco.github.io/blog/2024/07/27/interactive/
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用
评论