はじめに
データ構造の勉強のために競プロをやろうと思っており、そのためにテストを作りました。
よかったら使用してみてください。
デバッグ時にも標準入出力のまま実行できるため、提出時にコードを書き換える必要がなく、まあまあ便利かなと思います。
シェルスクリプト
コンパイルコマンドは$ make
としているので、同一ディレクトリにmakefile
を用意する必要がある。
makefile
を使わない場合は、make
部分をg++ main.cpp -o main.out
と変更すると良い。
input0 input1 ...
は、プログラムへの標準入力をあらかじめ用意する。output0 output1 ...
に関しては、用意しなくとも動作には影響を及ぼさないが実行時の便利のために用意した方が良い。
# !/bin/bash
# Compile
make
PRE_IFS=$IFS
IFS=$'\n'
# Put data {input output}
input0="1"
output0="1"
input1="2"
output1="2"
inputs=( ${input0} ${input1} ${input2} ${input3})
outputs=(${output0} ${output1} ${output2} ${output3})
# Test
for ((idx=0; idx<${#inputs[@]}; idx++))
do
echo "== Testing with input" ${idx} " ====="
echo ${inputs[${idx}]}
echo "------- Result ------------"
echo ${inputs[${idx}]} | ./main.out
echo "------- Answer ------------"
echo ${outputs[${idx}]}
done
echo "==========================="
解説
以下、各処理の簡単な説明を列挙する。
# !/bin/bash
# Compile
make
これはシバンとコンパイル。
# Put data {input output}
input0="1"
output0="1"
input1="2"
output1="2"
inputs=( ${input0} ${input1} ${input2} ${input3})
outputs=(${output0} ${output1} ${output2} ${output3})
ここでは、入力データおよび出力データを準備する。input0="1"
で、文字列として値を保存しており、inputs=( ${input0} ${input1} ... )
では、文字列の配列として各入力を保存する。この時、準備していない変数(input2, input3
)を配列の要素としたが、bashでは値の存在しないものを配列に入れても要素にされないようなのでこのように記述した。出力に関しても同様である。
# Test
for ((idx=0; idx<${#inputs[@]}; idx++))
do
echo "== Testing with input" ${idx} " ====="
echo ${inputs[${idx}]}
echo "------- Result ------------"
echo ${inputs[${idx}]} | ./main.out
echo "------- Answer ------------"
echo ${outputs[${idx}]}
done
echo "==========================="
IFS=$PRE_IFS
${#inputs[@]}
は入力配列の文字数を表し、for (( ... ))
によって準備された入力の個数だけidx=0, 1, ...
とループ処理を行う。for idx in ${#inputs[@]}
とするとidx=1, 2, ...
となってしまう点に注意する必要がある。echo ${input} | ./main.out
とすることで、echo ...
の結果をmain.out
の標準入力にパイプすることができる。
ループ内では、
- 何番目のテストなのか
- 入力内容
- 出力結果
- 正解
の情報を人の目で見てわかりやすいように適宜情報をecho
した。
おわりに
bashはほとんど書いたことがないので、不具合・改善策等あれば言ってもらえると幸いです。