4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rustで競プロ(のセッティング)

Posted at

Rust、使ってみたいなぁって思って、いつもやってるAtCoderで試してみようと思いました。

はじめに - AtCoderコンテストにRustで参加するためのガイドブック

を参考に、テストのあたりを改良してみました。実際に解くのはまだやってないです……

いろいろインストール

上記を参考にRustをインストール。さらにcargo-generateのインストール(同ガイドブック。以下略)をします。

ガイドに従って雛形のプロジェクトをゲットします

$ cargo generate --git https://github.com/rust-lang-ja/atcoder-rust-base --branch ja
🤷  Project Name: abc000
🔧   Creating project called `abc000`...
✨   Done! New project created /Users/ユーザー/programing/Rust/abc000

Project Name: のあとのabc000は自分で入力。

$ cd abc000

移動。

中身

  • abc000/src/main.rs

    ここに解答を書く。
  • abc000/tests
    テスト関係。主にここをいじる

カスタマイズ

テストケースの作成のところに、Rustのテスト機能を使ってテストケースを試す方法が載ってます。ただ、テストケースがプログラム中に書き込んであって ちょっとカッコ悪い/コピペする時位置調整がめんどい のでファイルから読み込むようにします。

rust: ファイル読み書き - nju33 を参考にabc000/tests/sample_inputs.rsを以下のように書き換えます。

use std::fs;
use cli_test_dir::*;

#[test]
fn sample() {
  let input = fs::read_to_string("tests/input.txt").unwrap();
  let output = fs::read_to_string("tests/output.txt").unwrap();

  let testdir = TestDir::new("main", "");
  let res = testdir.cmd()
    .output_with_stdin(input)
    .tee_output()
    .expect_success();
  assert_eq!(res.stdout_str(), output);
  assert!(res.stderr_str().is_empty());
}

途中の.tee_output()は、出力をテスト結果画面に出力するオプション、のようなものなので出力が長いとき等は削るのもあり。

さらに、入出力サンプルを入れるファイルをabc000/tests/input.txtabc000/tests/output.txtと作成します。ガイドライン通りに雛形をゲットしているとABC086 - C - Travelingの解答コードが入っているので、それに合わせて

input.txt
2
3 1 2
6 1 1

output.txt
Yes

とします。(特にoutput、最後の改行をやらないと一致判定で失敗するので注意)

お試し

テストしてみます。

$ cargo build

これはこのプロジェクトを使う前準備的なもの、らしい。proconioを使えるようにしたりする。

$ cargo test
   Compiling abc000 v0.1.0 (/Users/ユーザー/programing/Rust/abc000)
    Finished test [unoptimized + debuginfo] target(s) in 1.64s
     Running target/debug/deps/main-028731574152944b

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

     Running target/debug/deps/sample_inputs-c49f316d7d463d6e

running 1 test
Yes
test sample ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

サンプルの通過が判定できました!あとは各ケースをコピペすればいい。ctrl+A``ctrl+Vで全体を上書きできるので楽。

さらに改良

一致判定はしないで、単に出力をしてみたいときもあるのでabc000/tests/sample_inputs.rsを書き換えます。

use std::fs;
use std::io::Write; //new!!
use cli_test_dir::*;

#[test]
fn sample() {
  let input = fs::read_to_string("tests/input.txt").unwrap();
  let output = fs::read_to_string("tests/output.txt").unwrap();

  let testdir = TestDir::new("main", "");
  let res = testdir.cmd()
    .output_with_stdin(input)
    .tee_output()
    .expect_success();
//assert_eq!(res.stdout_str(), output); ここじゃなくて
  assert!(res.stderr_str().is_empty());

  //new!!
  let mut file = fs::File::create("tests/view.txt").unwrap();
  write!(&mut file, "{}", res.stdout_str()).unwrap();

  assert_eq!(res.stdout_str(), output); //後ろに回す
}

Rust - ファイルに書き込む | rust Tutorial を参考にしました。出力をabc000/tests/view.txtに書き出してくれます。

テストはエラーが出た時点で終了してしまうので、output.txtとの一致判定は最後に回しました。とにかくview.txtに出力して欲しいので。

おしまい

Rust、入力がめっちゃめんどくさい雰囲気だったんですけどproconioなるクレート(ライブラリ的な?)のおかげで楽にできます。ありがてぇ。

参考

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?