LoginSignup
5
1

More than 1 year has passed since last update.

[Atcoder][競プロ]サンプルテストを自動化

Last updated at Posted at 2021-03-11

##この記事でできるもの

とにかく楽をしたいから自動化を目指す

今回使った例題
https://atcoder.jp/contests/abc190/tasks/abc190_a

ターミナルで

$ rn a

と打つと

---------------情報----------------------
パス : /<path>/atcoder/abc/190
大会レベル : abc
大会番号 : 190
問題番号 : a
URL : https://atcoder.jp/contests/abc190/tasks/abc190_a

---------------エラー内容---------------
--------------------------------------

[INFO] online-judge-tools 11.1.3 (+ online-judge-api-client 10.8.0)
[INFO] 3 cases found
time: illegal option -- f
usage: time [-lp] <command>
[WARNING] GNU time is not available: time

[INFO] sample-1
[INFO] time: 0.055814 sec
[SUCCESS] AC    ←A問サンプル1のテスト結果

[INFO] sample-2
[INFO] time: 0.009793 sec
[SUCCESS] AC    ←A問サンプル2のテスト結果

[INFO] sample-3
[INFO] time: 0.009116 sec
[FAILURE] WA    ←A問サンプル3のテスト結果WAの場合以下が表示
input:          
2 2 1           ←サンプルの値

output:
Aoki            ←実行結果

expected:
Takahashi       ←正しい答え結果


[INFO] slowest: 0.055814 sec  (for sample-1)
[FAILURE] test failed: 2 AC / 3 cases

または文法を間違うと以下のように表示させる

---------------情報----------------------
パス : /<path>/atcoder/abc/190
大会レベル : abc
大会番号 : 190
問題番号 : a
URL : https://atcoder.jp/contests/abc190/tasks/abc190_a

---------------エラー内容---------------
./a.cpp: In function 'int main()':
./a.cpp:39:13: error: expected ';' before '}' token
   39 |     return 0
      |             ^
      |             ;
   40 | }
      | ~            
----------------------------------------------

また,自分のテストケースを実行したい場合

rn a test
---------------エラー内容---------------
---------------入力内容-----------------
1 1 1  <- 入力
No     <- 出力結果
----------------------------------------

とすることができる。

これを作る

##準備

こんなフォルダを用意する

└─atcoder
  ├─abc
  ├─arc
  ├─agc
  ├─coppy
  │ ├─a.cpp
  │ ├─b.cpp
  │ ├─c.cpp
  │ ├─d.cpp
  │ └─script.sh
  └─coppy.sh

##必要なこと
・ シェルスクリプトの使い方
・ エラーコードを読む気持ち

・ zsh bash(masOSの方はzshなのでこの記事を丸コピすれば動きます)

##作ってみる

online-judge-tools
の手順にしたがってojをダウンロード以下手順

% pip3 install --user online-judge-tools
ダウンロードの際,ojが存在するパスが表示される
/opt/home/..
/usr/local/bin/..
/Users/..
のどれか


% echo 'export PATH="/表示されたパス/bin:$PATH"' >> ~/.zshrc
//もしくは
% open ~/.zshrc

//bashの場合は .bashrc

#確認
% oj --version

###C++ファイル
a.cppやb.cppは
[競技プログラミング] C++ チートシート
のテンプレートを使うと便利

###script.sh

script.sh
# !/bin/sh
# 第一引数 問題番号
#  cd abc/190

alias g++='g++-10'

# 現在のパスを取得
path=$(cd $(dirname $0); pwd)

# コンテストレベル
contestLevel=${path##*atcoder/}
contestLevel=${contestLevel%/*}

# コンテスト番号
contestNumber=${path#*c/}

# 問題番号 引数
questionNumber="$1"


if [ $# -eq 2 ];then
  echo "---------------エラー内容---------------"
  # コンパイル
  g++ -Wall -std=c++14 ./${questionNumber}.cpp
  echo "---------------入力内容-----------------"
  ./a.out
  echo "----------------------------------------"
  rm -f a.out
  exit
fi



# AtCoderのURL
URL="https://atcoder.jp/contests/${contestLevel}${contestNumber}/tasks/${contestLevel}${contestNumber}_${questionNumber}"

# サンプルデータダウンロード
# oj login "${URL}"
oj dl "${URL}"


echo ""
echo "---------------情報----------------------"

echo "パス : "${path}
echo "大会レベル : "${contestLevel}
echo "大会番号 : "${contestNumber}
echo "問題番号 : "${questionNumber}
echo "URL : "${URL}
echo ""

echo "---------------エラー内容---------------"
# コンパイル
g++ -Wall -std=c++14 ./${questionNumber}.cpp

echo "----------------------------------------"
echo ""

# サンプルテスト
oj test

# 新しくできたファイルを削除
rm -f a.out
rm -rf test
ABC like(URLが定常と異なる)場合
URLはその都度入力
script.sh
#####################################################
alias g++='g++-10'

# AtCoderのURL
URL=""


# 問題番号 引数
questionNumber="$1"


if [ $# -eq 2 ];then
  echo "---------------エラー内容---------------"
  # コンパイル
  g++ -Wall -std=c++14 ./${questionNumber}.cpp
  echo "---------------入力内容-----------------"
  ./a.out
  echo "----------------------------------------"
  rm -f a.out
  exit
fi


# サンプルデータダウンロード
# oj login "${URL}"
oj dl "${URL}"


echo ""
echo "---------------情報----------------------"

echo "URL : "${URL}
echo ""

echo "---------------エラー内容---------------"
# コンパイル
g++ -Wall -std=c++14 ./${questionNumber}.cpp

echo "----------------------------------------"
echo ""

# サンプルテスト
oj test

# 新しくできたファイルを削除
rm -f a.out
rm -rf test

###coppy.sh

coppy.sh
# !/bin/sh
# 第一引数 コンテストレベル
# 第二引数 コンテスト番号
# sh coppy.sh abc 191

# 引数が正しく入力されていない場合
if [ ! $# -eq 2 ];then
  echo """
  -------ERROR-------
  コンテストレベルもしくは番号が正しく入力されていません
  AtCoder ABC 第190回コンテストなら
  sh coppy.sh abc 190
  と入力してください
  """
  exit
fi

# 現在のパスを取得 
path=$(cd $(dirname $0); pwd)

# コンテストレベル
contestLevel="$1"

# コンテスト番号
contestNumber="$2"

# コピー 上書き時警告表示
if [ -e ${path}"/"${contestLevel}"/"${contestNumber} ];then
  echo "同じ名前のファイルが以下のパスで見つかりました"
  echo ${path}"/"${contestLevel}"/"${contestNumber}
  read -p "上書きしますか? (y/N): " yn
  case "$yn" in
    [yY]*) rm -rf ${path}"/"${contestLevel}"/"${contestNumber}
              cp -r coppy ${contestNumber}
              mv ${contestNumber} ${contestLevel}
              echo "完了しました";;
    *) echo "キャンセルしました";;
  esac
else
  cp -r -i coppy ${contestNumber}
  mv ${contestNumber} ${contestLevel}
  echo "完了しました"
fi

もし間違ったパスを指定した場合

同じ名前のフォルダが以下のパスで見つかりました
/<path>/atcoder/abc/191
上書きしますか? (y/N): y
完了しました

##エイリアス設定
rn a でテスト実行するために

MacOS zsh環境なら

$ vim ~/.zshrc
または
$ open ~/.zshrc

vimの操作方法
1, i を押す(編集モード)
2, alias rn='sh script.sh'  ←を記入
3, escapeボタンを押す
4, :wq の順に押してEnter

#更新
$ source ~/.zshrc 

##環境設定完了

###コンテスト前のファイル作成

$ cd /<path>/atcoder/

#第191回abcコンテストのファイルを作成
$ sh coppy.sh abc 191 

###コンテスト中のテスト実行
実際にコンテスト中に使用したい場合は,AtCoderにログインする必要がある。
(コンテスト開始直前でよい)

$ oj login https://atcoder.jp/
AtCoderユーザー名:
パスワード:

第190回abcコンテストなら

$ cd /<path>/atcoder/abc/190

#A問題なら
$ rn a

#B問題なら
$ rn b
...

githubにコードがあるので参考にどうぞ

5
1
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
5
1