Skip to content

Instantly share code, notes, and snippets.

@riantkb
Last active December 30, 2020 09:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save riantkb/90080aecc5c7312170d6fcf572499663 to your computer and use it in GitHub Desktop.
Save riantkb/90080aecc5c7312170d6fcf572499663 to your computer and use it in GitHub Desktop.

(AtCoder の clar では文字数制限で書き切れなかったので gist で共有することにしました)

質問内容

ジャッジが壊れていませんか

  • 提出による確認は A 問題についてしかできていませんが、B 問題についても同様の問題を抱えていると予想しています

起きている現象

A 問題で入力を読んで stay を出力するコードを Python で提出したところ RE となったが、同じコードを Cython で提出したら AC となった。

原因だと予想している箇所

(以下で示すファイル構成及び行数は toolkit_A_v20201221, toolkit_B_v20201221 におけるものを示しています)

src/judge_A.lib/reactive.hpp 及び src/judge_B.lib/reactive.hpp の 39 行目に以下のようなコードがありますが、

execl(command.c_str(), command.c_str(), (char *)0);

このコードだと直接実行できる executable file を吐かない(AtCoder 上でそのような実行方法をとっていない)Java, Python, Ruby などの言語の提出を実行できない可能性があると思います(AtCoder のリアクティブジャッジがコンテスタントの提出の実行コマンドをどのような形式で渡しているのか知らないので正確なことは言えませんが……)。

https://atcoder.jp/contests/hokudai-hitachi2020/rules の実行コマンドの欄を読むと Python は python3.8 ./Main.py というコマンドで実行しますが Cython は ./a.out というコマンドで実行すると書かれているので、これが Python で通らず Cython で通った原因でないかと予想しています。

回避策としては、execl を使用するのなら

  • 第一引数にコマンドのフルパスを指定する
  • 与えられたコマンド全体を適切に parse し、引数に分けて execl に渡す

をする必要があると思います。

また、回避策として execl ではなく system 等を使用することもできるかもしれません。 自分が見たことのある同じようにリアクティブジャッジを実現するプログラムは、同様の処理を以下のような文で行っていました。

exit(system(command.c_str()) ? 1 : 0);

該当行を上の文に変更し、手元で

./judge_A "python a.py" < in.txt > result.txt

のように実行することで正常にジャッジができること(及び変更前は正常にジャッジできていないこと)を確認しています。

(pipe を実現するプログラムについては完全に初心者なので、間違っていたり不備があったりする可能性がありますがご容赦ください)

# 提出したコード
def seeklines(n):
for _ in range(n):
input()
def solve_a():
e = int(input().split()[1])
seeklines(e)
seeklines(1)
n_pat = int(input().split()[1])
seeklines(n_pat)
n_grid = int(input().split()[0])
seeklines(n_grid)
n_ev = int(input().split()[0])
seeklines(n_ev)
seeklines(1)
t_max = int(input())
for i in range(t_max + 1):
seeklines(n_grid)
seeklines(n_ev * 3)
if i < t_max:
for _ in range(n_ev):
print("stay", flush=True)
else:
seeklines(1)
solve_a()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment