我在Codeforce中遇到了一个交互问题.我想知道评分器或交互角色(根据Codeforce的条款)是如何设计的.

假设我想为这个问题创建一个评分器:1. Guess the Number.

我对上述问题的解决方案存储在1_Guess_the_Number.py文件中.这是一个正确的解决方案,并被CF分级机接受.

#!/usr/bin/env python3

l, r = 1, 1000000
while l != r:
    mid = (l + r + 1) // 2
    print(mid, flush=True)
    response = input()
    if response == "<":
        r = mid - 1
    else:
        l = mid

print("!", l)

我创建了以下grader.py个文件:

#!/usr/bin/env python3

import sys

INP = 12


def interactor(n):
    if n > INP:
        return "<"
    return ">="


while True:
    guess = input()
    if guess.startswith("!"):
        print(int(guess.split()[1]) == INP, flush=True)
        sys.exit()
    print(interactor(int(guess)), flush=True)

所以,当我运行./1_Guess_the_Number.py | ./grader_1.py的时候,我希望它能正常工作.但在终端中,上面的命令无限运行,只有以下输出:

<

我不知道哪里出了问题.此外,如果有人能提供任何其他方式,这将是非常有帮助的.

推荐答案

@user2357112的注释正确地描述了它无法工作的原因.当您的管道将第一个脚本的输出发送到评分器时,您没有向第一个脚本发送‘grader.py’的响应.

因此,我们需要做的是建立一种双向沟通.

这里有一个方法可以做到这一点.在评分器中,将您要测试的脚本命名为subprocess,并通过管道与其通信. 我在代码中添加了额外的解释.

1_Guess_the_Number.py和你的一样:

#!/usr/bin/env python3
l, r = 1, 1000000
while l != r:
    mid = (l + r + 1) // 2
    print(mid, flush=True)
    response = input()
    if response == "<":
        r = mid - 1
    else:
        l = mid

print("!", l)

grader.py接受测试文件的名称作为输入,并使用subprocess.Popen执行它:

# !/usr/bin/env python3
import sys
import subprocess

INP = 12

def interactor(n):
    if n > INP:
        return "<"
    return ">="

def decodeBytes(message):
    # Helperfunction to decode the message from stdin
    # guess has the format b'12345\r\n' 
    # rstrip() removes the \r\n, then we decode it as ascii
    return message.rstrip().decode('ascii')

if __name__ == '__main__':
    print(f'The secret answer is: {INP}')

    # get script name:
    name = sys.argv[1]
    print(f'calling script {name}')

    # start script as a subprocess
    p = subprocess.Popen(["python3", name], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
        
    # create iterator to read subsequent guesses
    stdout_iterator = iter(p.stdout.readline, b"")

    # loop over all guesses
    for msg_in in stdout_iterator:

        #msg_in is a byte array, we need to decode it
        guess = decodeBytes(msg_in)
        print(f'got msg: {guess}')

        if guess.startswith("!"):
            final_answer = int(guess.split()[1])
            print(f'The final answer is: {final_answer}')
            if final_answer == INP:
                print('Answer was correct!')
                break
            print('Answer is wrong!')
            break
        
        # we determine the message to send out
        msg_out = interactor(int(guess))
        print(f'send msg: {msg_out}')
        
        # sending it to the scripts stdin. 
        p.stdin.write((msg_out + '\n').encode())
        # we need to flush stdin, to make sure the message is not stuck in a buffer
        p.stdin.flush()

在命令行中,您可以通过以下方式调用评分器

python grader.py 1_Guess_the_Number.py

打印输出为:

The secret answer is: 12
calling script 1_Guess_the_Number.py
got msg: 500001
send msg: <
got msg: 250001
send msg: <
got msg: 125001
send msg: <
got msg: 62501
send msg: <
got msg: 31251
send msg: <
got msg: 15626
send msg: <
got msg: 7813
send msg: <
got msg: 3907
send msg: <
got msg: 1954
send msg: <
got msg: 977
send msg: <
got msg: 489
send msg: <
got msg: 245
send msg: <
got msg: 123
send msg: <
got msg: 62
send msg: <
got msg: 31
send msg: <
got msg: 16
send msg: <
got msg: 8
send msg: >=
got msg: 12
send msg: >=
got msg: 14
send msg: <
got msg: 13
send msg: <
got msg: ! 12
The final answer is: 12
Answer was correct!

Python相关问答推荐

时间序列分解

max_of_three使用First_select、second_select、

查找两极rame中组之间的所有差异

pandas滚动和窗口中有效观察的最大数量

C#使用程序从Python中执行Exec文件

如何在类和classy-fastapi -fastapi- followup中使用FastAPI创建路由

在vscode上使用Python虚拟环境时((env))

如何在Polars中从列表中的所有 struct 中 Select 字段?

用砂箱开发Web统计分析

在Python 3中,如何让客户端打开一个套接字到服务器,发送一行JSON编码的数据,读回一行JSON编码的数据,然后继续?

Pandas Data Wrangling/Dataframe Assignment

如何检测鼠标/键盘的空闲时间,而不是其他输入设备?

不允许 Select 北极滚动?

当输入是字典时,`pandas. concat`如何工作?

极点替换值大于组内另一个极点数据帧的最大值

如何根据一定条件生成段id

操作布尔值的Series时出现索引问题

pytest、xdist和共享生成的文件依赖项

修改.pdb文件中的值并另存为新的

TypeError:';Locator';对象无法在PlayWriter中使用.first()调用