0
0

インタラクティブ問題でpexpectがいい感じだった話

Posted at

とあるABC337にて

こんな問題が出てきました。

具体的な問題は実際に見てもらうとして、本題はこれがインタラクティブ問題だということです。
つまりコードテストにぶちこむだけでは合ってるかどうかすらわからない。これではペナりまくってしまう。
ですのでテスターをサクッと自作したいと思います

subprocessを使う

やばい、めんどい、使いたくない。
pipeとかを使えば行けるぽいですが、osレベルの話に関わってくるのでコンテスト中に作成するのは断念

pexpectを使う

subprocess以外に出てきたいい感じのやつです。
以下ここからサンプルコード

# This connects to the openbsd ftp site and
# downloads the recursive directory listing.
import pexpect
child = pexpect.spawn('ftp ftp.openbsd.org')
child.expect('Name .*: ')
child.sendline('anonymous')
child.expect('Password:')
child.sendline('noah@example.com')
child.expect('ftp> ')
child.sendline('lcd /tmp')
child.expect('ftp> ')
child.sendline('cd pub/OpenBSD')
child.expect('ftp> ')
child.sendline('get README')
child.expect('ftp> ')
child.sendline('bye')

単純で使いやすそうです。

そして以下が作ったテスターになります

import random
import pexpect
import time
    
def main(n):
    
    p = pexpect.spawn('python3 e.py')
    x = random.randint(1,n)
    #print("n:",n)
    p.sendline(str(n))
    p.expect("\n")
    m = p.before.decode(encoding='utf-8')
    p.expect("\n")
    m = p.before.decode(encoding='utf-8')
    print("n:",n,"m:",m)
    m = int(m)
    result = ""
    for i in range(m):
        p.expect("\n")
        s = p.before.decode(encoding='utf-8').split()
        #print(f"{i+1}:",s)
        s = list(map(int,s))[1:]
        if x in s:
            result+="1"
        else:
            result+="0"
    p.sendline(result)
    p.expect("\n")
    s = p.before.decode(encoding='utf-8')
    p.expect("\n")
    s = p.before.decode(encoding='utf-8')
    if int(s)!=int(x): #or not(2**m>n and 2**(m-1)<=n):
        print("n:",n)
        print("s:",s)
        print("x:",x)
        time.sleep(9999)


if __name__ == "__main__":
    while True:
        for i in range(2,101):
            main(i)

注意点

  1. どうやらWindowsで動かすのはめんどくさいらしい
    Window上で動かすとどういうわけかエラーを吐く、Linuxなら上手くいくらしいのでWSLで代用

  2. 一部の入力は二回連続受け取らないといけないぽい
    なんでだ?まぁこれで上手くいくので別に問題ない

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0