LoginSignup
2
1

More than 5 years have passed since last update.

Emacs で AtCoder のサンプルケースを一括テスト

Last updated at Posted at 2018-12-28

どうも、退職アドカレを書こうと思ってエントリーだけして逃げた者です。

必要なもの

emacs-quickrun の標準入力

前述の emacs-quickrun では ソースファイル名(含拡張子).qrinput としてファイルを定義すると、そのファイルの内容が実行時に標準入力として渡されるようになります。しかし、この仕様では標準入力を1つまでしか用意できません。
そこで、 AtCoder が用意する2~3のテストケースを一括でテストする方法を考えました。

テストスクリプト

詳しい実装はあまりにも自明なので説明しません。
カレントディレクトリから input-*.txtoutput-*.txt を探してそれぞれにテストを実行します。

#!/usr/bin/env bash

set -u
IFS=$'\n\t'

# run-tests.sh --- Run AtCoder test cases
# author: Seong Yong-ju <sei40kr@gmail.com>

red="$(tput setaf 1)"
green="$(tput setaf 2)"
yellow="$(tput setaf 3)"
bold="$(tput bold)"
reset="$(tput sgr0)"

cmd="$@"
buffile="$(mktemp)"
errfile="$(mktemp)"

shopt -s nullglob

for infile in input-*.txt; do
    outfile="output-${infile:6}"
    if [[ ! -f $outfile ]]; then
        continue
    fi

  echo -n "${infile} - "

    eval "${cmd[@]}" <"$infile" 1>"$buffile" 2>"$errfile"
    if [[ "$?" != 0 ]]; then
        cat <<EOM
${bold}${red}err${reset}

error output:
$(cat "$errfile")

EOM
        break
    fi

    if diff -q "$buffile" "$outfile" >/dev/null; then
        echo "${bold}${green}ok${reset}"
    else
        cat <<EOM
${bold}${yellow}ng${reset}

expected:
$(cat "$outfile")

actual:
$(cat "$buffile")

EOM
    fi
done

rm -f "$buffile" "$errfile"

本当はTLEのチェックもしたかったのですが、まあいいや。

テストケースを用意する

こんな感じで。

input-1.txt
5 2
output-1.txt
1 7
input-2.txt
1 10 0

ちなみにこれを自動化するために、 Python でツールを書きました。
https://github.com/sei40kr/atcoder-scraper

$ atcoder-scraper https://atcoder.jp/contests/abc090/tasks/arc091_b

こんな感じです。ちなみにこれの完全上位互換のツールが存在することを作った後に知りました。
https://github.com/kyuridenamida/atcoder-tools

Spacemacs の quickrun レイヤー

今言っても仕方ありませんが、以前は Spacemacs の quickrun 用のレイヤーを作っていました。
ソースコードのファイル名(含拡張子).qrinput* 形式のファイルが複数ある場合に helm で選べるようにするものです。
https://github.com/sei40kr/spacemacs-quickrun

.dir-locals.el の設定

ソースコードを置いているプロジェクトの先祖ディレクトリのどこかに .dir-locals.el を用意して、 quickrun の実行コマンドを書き換えます。
プロジェクトのルートを特定するために eval を使ってます。適宜変更してください。
ちなみに 1.15.1 は AtCoder の Rust のバージョンです。 rustc --emit=mir がないので同じバージョンでLinterを動かせない...。

;;; .dir-locals.el ---                               -*- lexical-binding: t; -*-

;; Copyright (C) 2018 Seong Yong-ju

;; Author: Seong Yong-ju <sei40kr@gmail.com>

((rust-mode . ((racer-rust-src-path . "~/.rustup/toolchains/1.15.1-x86_64-apple-darwin/lib/rustlib/src/rust/src")
                 (eval . (setq quickrun-option-cmd-alist
                           (list
                             '(:command . "rustup")
                             (cons :exec
                               (list
                                 "%c run --install 1.15.1 rustc %o -o %e %s"
                                 (concat (projectile-project-root) "utils/run-tests.sh env RUST_BACKTRACE=1 %e %a")))
                             '(:compile-only . "%c run --install 1.15.1 rustc %o -o %e %s")
                             '(:remove . ("%e"))
                             '(:description . "Compile rust and execute via rustup")))))))

[先程のスクリプト] [実行コマンド...] といった感じですね。テストケースの数に依らず、コンパイルは1回です。

結果

スクリーンショット

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