Memo

Twitterに書くには長すぎることを書きます。Opinions are my own.

デバッグ出力マクロはインタラクティブ問題と相性がいい

コンパイラオプションに -DLOCAL を仕込んでおくと、こんなデバッグ出力マクロが書けることが知られている。

void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}
#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

これはtourist氏のものだが、このようなマクロを書くことで、手元ではデバッグ出力するがコードがsubmitされた環境では何も起こらない、という便利なことができる。cerr出力する場合は大量に呼び出すと遅くなるが、マクロの場合はそもそもsubmitされた環境で出力が呼び出されないので速度のことをほとんど考えずに使えて便利。

ここからが本記事の本題だが、この仕組みはインタラクティブ問題でも使えて、テストしたいときにいちいちコードを書き換えなくてすむという利点がある。例えばこんな感じ

char check(ll n) {
#ifdef LOCAL
  if ((n > K) ^ (to_string(n) > to_string(K))) {
    return 'N';
  } else {
    return 'Y';
  }
#else
  cout << "? " << n << endl;
  char c; cin >> c;
  return c;
#endif
}

実際の提出: Submission #6014548 - AtCoder Regular Contest 078 (ARC078-E)

すでに自明なのかもしれないが、気づいたとき感動した。

GCJだとテスト用のツールがすでに用意されているのでそっちを使いましょう。

$ python interactive_runner.py python testing_tool.py 0 -- ./a.out