beet's soil

競プロのことなど

Online Judge Verify Helper のススメ

書いた えらい

この記事は Competitive Programming (1) Advent Calendar 2019 の24日目の記事です。
adventar.org

TL; DR;

github.com

実例

https://github.com/beet-aizu/library/actions

f:id:beet_aizu:20191221164553p:plain
❌はライブラリがバグっていることを、✅はバグが修正されたことを表す

ドキュメント生成の例

つたじぇーさんがやってくれました これかなりすごいと思う(コナミ
どのファイルがどのファイルに依存しているかとかが視覚化されていて、うれしい
beet-aizu.github.io


え、書くことがありません 終わり

2019/12/25 追記


たしかに〜〜〜〜

2019年時点での仕様です。
基本的にもう更新しないので、最新の情報を知りたければgithubの方を見てください。

ドキュメント整備を進めていきたいとは思っています。(だれか自動化してくれ)

2019/12/24追記

機能紹介

これレポジトリにないのやばへん?Online Judge Verify Helperはエスパー以外お断りツール

以下はテストファイルの一例です

#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2187"

#include<bits/stdc++.h>
using namespace std;

#define call_from_test
#include "../../tools/fastio.cpp"
#include "../../tools/chminmax.cpp"
#include "../../tools/all_permutations.cpp"
#undef call_from_test

#define ERROR "1e-5"

signed solve(){
  const int n=9;
  vector<int> as(n),bs(n);
  for(int i=0;i<n;i++) cin>>as[i];
  for(int i=0;i<n;i++) cin>>bs[i];
  int num=0,cnt=0;
  auto f=
    [&](vector<int> vs){
      int x=0,y=0;
      for(int i=0;i<n;i++){
        if(as[vs[i]]<bs[i]) x+=as[vs[i]]+bs[i];
        if(as[vs[i]]>bs[i]) y+=as[vs[i]]+bs[i];
      }
      if(x<y) num++;
      cnt++;
    };
  all_permutations(n,f);

  double A=(double)num/cnt;
  double B=1.0-A;
  cout<<fixed<<setprecision(5);
  cout<<A<<" "<<B<<endl;
  return 0;
}

signed main(){
  int T;
  cin>>T;
  while(T--) solve();
  return 0;
}
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2187"

の行で、テストデータのダウンロード先を指定します。
AOJとLibrary Checkerに対応しています。
たまにAOJの古い問題のテストケースが公開されていないことがあるので、そういう時は僕に連絡してもらえると対応できる可能性があります。

Library Checkerの問題はcheckerに対応しているので、PROBLEMだけ設定すればよいです。

AOJ の問題はまだcheckerに対応していないので、誤差ジャッジの場合は追加でマクロが必要になります。

#define ERROR "1e-5"

のように指定します。

あるテストを無視する場合は

#define IGNORE

とします。内部ではコンパイラプリプロセッサを利用しているため、ifdef等と組み合わせることも可能です。

2019/12/25追記
ただし、IGNOREをするとドキュメント生成が行われなくなります。

環境設定

TODO: githubの方にドキュメントを書く

現状デフォルトでは g++ と clang++ でテストを行なっています

注意として、GitHub上ではclang++ でもbits/stdc++.h を使えます、__gcdとかは無理だったはず
github.com

コードを読んでもらえれば分かるのですが、環境変数 CXX にコンパイラを指定すればそれでテストされるようになります。
github.com

同様に、コンパイラオプションを変更したい場合は環境変数 CXXFLAGS を指定すればよいです。

GitHub Actionsで環境変数を設定するには、verify.yml の

    - name: Run tests
      env:
        GH_PAT: ${{ secrets.GH_PAT }}
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: oj-verify all -j 2

    - name: Run tests
      env:
        CXX: g++
        GH_PAT: ${{ secrets.GH_PAT }}
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: oj-verify all -j 2

のように書き換える必要があります 詳しくは公式のガイドを参照してください
help.github.com

また、あるファイルの特定のコンパイラだけスキップしたいという状況の場合は、マクロを用いて

#ifdef __clang__ 
#define IGNORE
#endif

などとすればスキップされます。

モチベーション

ライブラリのverify作業、つらすぎ… → 自動化!(素振り)
github.com

経緯

全てはここから始まった… 
github.com
最初はtravisでやっていました

verify結果を保存したいというモチベーションがあり、GitHub Actionsを知ったのでどうにかpushできないか調べたらできた
beet-aizu.hatenablog.com

online-judge-tools がbtkさんの手によりスペシャルジャッジに対応

ICPC 2019 Yokohamaでkmykさんにそそのかされてツール化を決意

仕組み

online-judge-tools というツールを内部で利用しています。
github.com

online-judge-tools を使うと、テストケースのダウンロードからジャッジまでをCUIから行えます。

レポジトリに push されるたびに、テスト用ファイル(と依存しているファイル)が更新されているかをコミットログから判定します。

更新されていたら、online-judge-tools でテストを行い、結果をjsonファイルに保存します。

書いてからみるとめっちゃやることシンプルだな やっぱシェルからpythonに移行したのが一番大変だったな!

これからやること

Library Checker(通称よすぽジャッジ)に問題案を追加していきたい
judge.yosupo.jp

問題を探してみてなかったら↓にコメントを書くと誰かが準備してくれるかもしれない、これを読んでいるあなたが準備してくれてもいいんですよ
github.com

お願い

yukicoder のデータセットも使いたい、使いたくない…?

ユーザーが増えると、yukiさんを説得しやすくなるので、頼む

導入したユーザー一覧は ↓みたいに取れるので、頼む
github.com