Last active
May 29, 2021 04:40
-
-
Save naoyat/d4a0778fd6aa543d23e0138582208db9 to your computer and use it in GitHub Desktop.
典型#053用インタラクティブジャッジツール
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# | |
# Problem 053 judge tool, by naoya_t | |
# | |
# eg.) | |
# python 053_judge.py ./a.out -- test random 50 cases, with qmax=15 (小課題4; default) | |
# python 053_judge.py -q 2 ./a.out -- test random 50 cases, with qmax=40 (小課題2) | |
# python 053_judge.py -n 1500 -k 1 -q 3 ./a.out -- test a particular case, with qmax=22 (小課題3) | |
# python 053_judge.py -a -q 4 ./a.out -- test all cases, with qmax=15 (小課題4) | |
# | |
import sys | |
import traceback | |
import subprocess | |
import argparse | |
from random import randint | |
_verbose = False | |
def debug(*items): | |
if _verbose: | |
print("::", end=' ', file=sys.stderr) | |
print(*items, file=sys.stderr) | |
def colored(ansi_num, msg): | |
def ansi(num): | |
return '\x1b[%dm' % num | |
return ansi(ansi_num) + msg + ansi(0) | |
def say(msg): | |
sys.stdout.write(msg + '\n') | |
sys.stdout.flush() | |
def main(): | |
parser = argparse.ArgumentParser(description='典型#053用インタラクティブジャッジツール') | |
parser.add_argument('agent', type=str) | |
parser.add_argument('-v', '--verbose', action='store_true', default=False) | |
parser.add_argument('-a', '--test-all', action='store_true', default=False) | |
parser.add_argument('-t', '--t', type=int, default=50) | |
parser.add_argument('-n', '--fixed-n', type=int, default=-1) | |
parser.add_argument('-k', '--fixed-k', type=int, default=-1) | |
parser.add_argument('-q', '--q', type=int, default=4) | |
args = parser.parse_args() | |
global _verbose | |
_verbose = args.verbose | |
if args.test_all: | |
t = (1 + 1500) * 1500 // 2 | |
elif args.fixed_k > 0: | |
t = 1 | |
else: | |
t = args.t | |
QMAX = { 1: 1500, 2: 40, 3: 22, 4: 15 } | |
qmax = QMAX[args.q] | |
try: | |
agent = args.agent | |
if '/' not in agent: | |
agent = './' + agent | |
p = subprocess.Popen([agent], stdin=subprocess.PIPE, stdout=subprocess.PIPE) | |
def send_to_agent(msg): | |
p.stdin.write(msg.encode('ascii') + b'\n') | |
p.stdin.flush() | |
def receive_from_agent(): | |
return p.stdout.readline().decode().strip() | |
### | |
send_to_agent("%d" % t) | |
def turn(z, n, k): | |
debug("TURN %d: n=%d k=%d" % (z, n, k)) | |
a = [n - abs(k - i) + 1 for i in range(n+1)] | |
send_to_agent("%d" % n) | |
ask_count = 0 | |
while True: | |
# debug("(残弾数 %d)" % (15 - ask_count)) | |
fs = receive_from_agent().split(' ') | |
assert len(fs) == 2 | |
if fs[0] == '?': | |
x = int(fs[1]) | |
assert 1 <= x <= n | |
# debug("asked a[%d] = %d" % (x, a[x])) | |
ask_count += 1 | |
send_to_agent("%d" % a[x]) | |
elif fs[0] == '!': | |
ak = int(fs[1]) | |
if ask_count > qmax: | |
verdict = "QUERY LIMIT EXCEEDED" | |
elif ak == a[k]: | |
verdict = "PASSED" | |
else: | |
verdict = "FAILED" | |
print("Test Case #%d...%s (q=%d)" % (z, verdict, ask_count)) | |
break | |
else: | |
assert False | |
if args.test_all: | |
z = 1 | |
for n in range(1, 1+1500): | |
for k in range(1, 1+n): | |
turn(z, n, k) | |
z += 1 | |
else: | |
for z in range(1, 1+t): | |
if args.fixed_n > 0: | |
n = args.fixed_n | |
else: | |
n = randint(1, 1500) | |
if args.fixed_k > 0: | |
k = args.fixed_k | |
if k > n: | |
k = 1 + ((k-1) % n) | |
else: | |
k = randint(1, n) | |
turn(z, n, k) | |
p.wait() | |
except Exception: | |
traceback.print_exc() | |
p.kill() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment