diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 84fc4df..3f3f686 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -2,25 +2,25 @@ # Summary -- [はじめに (TODO)](./introduction.md) -- [AtCoderの環境について (TODO)](./todo.md) - - [ソフトウェアのバージョンなど (TODO)](./todo.md) - - [単一のソースファイル (TODO)](./todo.md) - - [利用可能なクレート (TODO)](./todo.md) -- [開発環境の準備 (TODO)](./todo.md) - - [Rustツールチェインのインストール (TODO)](./todo.md) - - [ソースコードエディタとデバッガの準備 (TODO)](./todo.md) - - [cargo-generateテンプレート (TODO)](./todo.md) - - [cargo-generateのインストール (TODO)](./todo.md) -- [コンテストの参加方法 (TODO)](./todo.md) - - [Cargoパッケージの作成 (TODO)](./todo.md) - - [利用するクレートの選択 (TODO)](./todo.md) - - [テストケースの作成 (TODO)](./todo.md) - - [プログラムの作成 (TODO)](./todo.md) - - [プログラムのテスト (TODO)](./todo.md) - - [プログラムの提出 (TODO)](./todo.md) -- [Tips(小技集) (TODO)](./todo.md) - - [クレートの使用例 (TODO)](./todo.md) +- [はじめに](./introduction.md) +- [AtCoderの環境について](./environment.md) +- [開発環境の準備 (TODO)](./installation/index.md) + - [Rustツールチェインのインストール (TODO)](./installation/toolchain.md) + - [ソースコードエディタの準備 (TODO)](./installation/editor.md) + - [Rust Language Server のインストール](./installation/rls.md) + - [cargo-generateのインストール](./installation/cargo-generate.md) +- [コンテストの参加方法 (TODO)](./participate/index.md) + - [コンテスト直前の事前準備](./participate/before-contest/index.md) + - [Cargoパッケージの作成 (TODO)](./participate/before-contest/generate-project.md) + - [利用するクレートの選択とコンパイル (TODO)](./participate/before-contest/choose-crates.md) + - [プロジェクトのコピー (TODO)](./participate/before-contest/copy-project.md)] + - [コンテスト開始後の流れ](./participate/during-contest/index.md) + - [テストケースの作成](./participate/during-contest/write-tests.md) + - [プログラムの作成 (TODO)](./participate/during-contest/write-program.md) + - [プログラムのテスト](./participate/during-contest/test.md) + - [プログラムの提出 (TODO)](./participate/during-contest/submit.md) +- [Tips(小技集) (TODO)](./tips.md) + - [クレートの使用例](./use-crates.md) - [AtCoder運営者向けの情報](./atcoder-env/index.md) - [本章で想定している環境](./atcoder-env/supported-environment.md) - [インストール](./atcoder-env/installation.md) diff --git a/src/atcoder-env/compiling-and-running-using-cargo.md b/src/atcoder-env/compiling-and-running-using-cargo.md index 1e99a9c..be9b62e 100644 --- a/src/atcoder-env/compiling-and-running-using-cargo.md +++ b/src/atcoder-env/compiling-and-running-using-cargo.md @@ -1,3 +1,5 @@ + + # [cargo] ファイルレイアウトとコンパイルの流れ 選手がRustプログラムを提出すると、その内容がジャッジサーバ上のファイルシステムに書き出されます。 @@ -21,7 +23,8 @@ $HOME # ユーザのホームディレクトリ 以上でCargoプロジェクトが整いました。 -# コンパイルコマンド + +## コンパイルコマンド ツールチェインのインストールのページで説明したように、コンパイルを実行するシェルに以下の環境変数が設定されている必要があります。 diff --git a/src/atcoder-env/compiling-and-running-using-rustc.md b/src/atcoder-env/compiling-and-running-using-rustc.md index 82f9360..2aae656 100644 --- a/src/atcoder-env/compiling-and-running-using-rustc.md +++ b/src/atcoder-env/compiling-and-running-using-rustc.md @@ -1,3 +1,5 @@ + + # [rustc] ファイルレイアウトとコンパイルの流れ 選手がRustプログラムを提出すると、その内容がジャッジサーバ上のファイルシステムに書き出されます。 @@ -25,7 +27,7 @@ $HOME ``` -# コンパイルコマンド +## コンパイルコマンド ツールチェインのインストールのページで説明したように、コンパイルを実行するシェルに以下の環境変数が設定されている必要があります。 diff --git a/src/atcoder-env/installing-rust-crates.md b/src/atcoder-env/installing-rust-crates.md index e645069..edbb78c 100644 --- a/src/atcoder-env/installing-rust-crates.md +++ b/src/atcoder-env/installing-rust-crates.md @@ -20,6 +20,7 @@ - 例:標準ライブラリのハッシュ関数はDoS攻撃を避けるために暗号強度があり、計算量が多い。 競技プログラミングでは暗号強度は求められず、より計算量の少ないハッシュ関数で十分 + ### AtCoder運営者様へのお願い 対象クレートの一覧は[このページ][crates-2019]にあります。 @@ -38,6 +39,7 @@ `cargo build`コマンドを実行すると、Cargoはそれらのクレートのソースコードをダウンロードし、適切なオプションと共に`rustc`を実行することでクレートをコンパイルします。 クレートのソースコードは`$CARGO_HOME/registory/src`にダウンロードされ、コンパイル済みのクレート(`rlib`ファイル)は`Cargo.toml`が置かれたディレクトリを起点とする相対ディレクトリ`./target/release/deps`配下に出力されます。 + ### 一般的な開発時のファイルレイアウト ```console @@ -63,6 +65,7 @@ $HOME # ユーザのホームディレクトリ まず、今回は各ファイルを以下のように配置し、クレートのコンパイルは導入時に済ませておくことにします。 + ### AtCoderジャッジサーバでのファイルレイアウト(導入時に配置するもの) ```console @@ -82,6 +85,7 @@ $RUST_HOME (/usr/local/lib/rust) そしてジャッジの際には[以前説明した](./supported-environment.md#一般的なrustプログラム開発環境との違い)Cargoを利用する方法と`rustc`を利用する方法のいずれかを利用してコンパイルします。 + ### [cargo] AtCoderジャッジサーバでのファイルレイアウト(ジャッジの際に作成するもの) ```console @@ -96,6 +100,7 @@ $HOME # ユーザのホームディレクトリ └-- atcoder-rust-base # コンパイル、リンク済みの実行ファイル ``` + ### [rustc] AtCoderジャッジサーバでのファイルレイアウト(ジャッジの際に作成するもの) Cargoを使用せず、`rustc`に適切なオプション(ライブラリ検索パスなど)を与えて実行することで、事前にコンパイルしておいた`rlib`ファイルとリンクさせます。 @@ -343,6 +348,7 @@ _108 = {package = "whiteread",version = "=0.4.4",default-features = false,featur [the-cargo-book-platform-specific-dependencies]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#platform-specific-dependencies [the-cargo-book-specifying-dependencies]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#specifying-dependencies + ## クレートのコンパイル クレートをコンパイルしましょう。 @@ -371,4 +377,3 @@ $ find target/release/deps/ -type f | egrep -c '\.(rlib|so)$' 66 # ↑ 上の数字を確認 ``` - diff --git a/src/atcoder-env/installing-rustc-dep-option-generator.md b/src/atcoder-env/installing-rustc-dep-option-generator.md index 73d3722..150e5a6 100644 --- a/src/atcoder-env/installing-rustc-dep-option-generator.md +++ b/src/atcoder-env/installing-rustc-dep-option-generator.md @@ -2,7 +2,7 @@ # (オプション)クレート検索パス生成ツールのインストール -**Note:** この作業は実際のビルドに`rustc`を利用する場合で、クレート検索パスを指定するコンパイルオプションをツールで生成する場合に必要となります。実際のビルドで`cargo`を利用する場合と`cargo build -v`などの出力を元にしてクレート検索パスを指定するコンパイルオプションを手書きする場合などはツールは不要です。 +> Note: この作業は実際のビルドに`rustc`を利用する場合で、クレート検索パスを指定するコンパイルオプションをツールで生成する場合に必要となります。実際のビルドで`cargo`を利用する場合と`cargo build -v`などの出力を元にしてクレート検索パスを指定するコンパイルオプションを手書きする場合などはツールは不要です。 このページでは`rustc`のコマンドライン・オプションを生成するツールである`rustc-dep-option-generator`のインストール手順を説明します。 このツールはRustで書かれています。 @@ -19,6 +19,7 @@ $ sudo apt install -y libssl-dev なお`libssl-dev`は`rustc-dep-option-generator`が`cargo`をライブラリとして用いているために必要ですが、このツールではその機能は使いません。ツール実行時のネットワーク・アクセスは不要です。 + ## ツールのインストール `cargo install`コマンドでインストールします。 diff --git a/src/atcoder-env/supported-environment.md b/src/atcoder-env/supported-environment.md index 519c72a..e9627bc 100644 --- a/src/atcoder-env/supported-environment.md +++ b/src/atcoder-env/supported-environment.md @@ -2,6 +2,7 @@ # 本章で想定している環境 + ## 用語 まずは用語を整理します。本章で用いる用語には以下のものがあります。 diff --git a/src/environment.md b/src/environment.md new file mode 100644 index 0000000..90f3406 --- /dev/null +++ b/src/environment.md @@ -0,0 +1,10 @@ + + +# AtCoderの環境について + +現在 AtCoder で利用できる最新の環境は 2020 年言語アップデートによって更新された環境です。 + +- Rust 1.42.0 +- 外部クレートあり + +コンパイルオプションや利用できる外部クレートの一覧と簡単な解説やコード例など、この環境についてのより詳しい情報は [2020 Update](https://github.com/rust-lang-ja/atcoder-rust-resources/wiki/2020-Update) のページにまとまっています。ご一読ください。 diff --git a/src/installation/cargo-generate.md b/src/installation/cargo-generate.md new file mode 100644 index 0000000..25ad201 --- /dev/null +++ b/src/installation/cargo-generate.md @@ -0,0 +1,41 @@ + + +# `cargo-generate` のインストール + +AtCoder で利用できる Rust のバージョンやライブラリを指定したプロジェクトを簡単に生成するために、 [atcoder-rust-base の ja ブランチ](https://github.com/rust-lang-ja/atcoder-rust-base/tree/ja)にプロジェクトの雛形を用意しています。この雛形は`cargo generate`というコマンドを使って展開するため、先にこのコマンドをインストールする必要があります。 + +`cargo generate` サブコマンドを利用できるようにするには `cargo-generate` が必要です。端末 (Windows ユーザーの方はコマンド プロンプト) を開いて `cargo install cargo-generate` コマンドを実行してください。これだけでインストールは完了です。 + +```console +$ cargo install cargo-generate + Updating crates.io index +Downloaded cargo-generate v0.5.0 +(...中略...) + Compiling cargo-generate v0.5.0 + Finished release [optimized] target(s) in 5m 46s +Installing ... + Installed package `cargo-generate v0.5.0` (executable `...`) +``` + +実際に `cargo generate --help` として実行できるかどうかを確認しましょう。 + +```console +$ cargo generate --help +cargo-generate 0.5.0 +Ashley Williams +cargo, make me a project + +USAGE: + cargo generate [FLAGS] [OPTIONS] --git + +FLAGS: + -f, --force Enforce to create a new project without case conversion of project name + -h, --help Prints help information + -V, --version Prints version information + -v, --verbose + +OPTIONS: + --branch + --git + -n, --name +``` diff --git a/src/installation/editor.md b/src/installation/editor.md new file mode 100644 index 0000000..c58dfb8 --- /dev/null +++ b/src/installation/editor.md @@ -0,0 +1,22 @@ + + +# ソースコードエディタの準備 + +Rust プログラムのソースコードは単純なテキストファイルです。編集にはテキストエディタというプログラムを使います。単純にテキストを読み書きするという機能に限ればテキストエディタは OS にも付属していますが、よりプログラミングに特化した機能を多く揃えるテキストエディタが無料で簡単に使える時代ですので、ぜひ活用するべきです。それらのエディタが持つ機能には例えば次のようなものがあります。 (一例です) + +- コードハイライト + 文法構造に合わせてソースコードを色付けして表示する機能です。たとえば型名や関数名などに色がつきます。この機能はコードを視覚的に把握するのに役立ちます。 +- 入力補完 + 変数名や関数名の最初の何文字かを入力するだけでそれから始まる要素を列挙して表示してくれます。目当てのものがあればキー一つで残りの部分を補完してくれます。 +- エラーハイライト + 入力するのと同時にリアルタイムに内容をチェックし、エラーがあればそれをエディタ上に赤線を引くなどの形で表示してくれます。コンパイラを直接実行する手間もエラーメッセージを読み解く手間もなくエラーに気づくことができるメリットがあります。 +- ドキュメント (説明書き) の表示 + 久しぶりに使う関数の引数の数や順番がわからなくなることはよくあることですが、こういうときにマウスカーソルを関数に合わせるだけでその関数のシグネチャやドキュメントを表示してくれます。 +- 定義へのジャンプ + その関数や型が定義されている場所を開いてくれます。構造体の中身を少し忘れてしまったり、関数の処理の中身を確認したりといったときに簡単にソース上を移動できます。 + +こういった機能は Language Server Protocol という共通の仕組みの上に実装されているので、これをサポートするエディタであればこれらの機能を享受できます。 Language Server Client を実装しているエディタは無数にあり、どれを使うかは完全に好みです。 + +本説明はできるだけエディタによらないように進めていくつもりですが、エディタに特有の内容が現れるときは [Visual Studio Code](https://code.visualstudio.com/) を想定して説明します。それ以外のエディタを使われる方は適宜読み替えてお読みください。次節で Rust のコーディング支援機能を導入する方法を説明します。 + +(TODO: Visual Studio Code のインストールと Rust (rls) 拡張機能のインストールを説明する) diff --git a/src/installation/index.md b/src/installation/index.md new file mode 100644 index 0000000..27d0c11 --- /dev/null +++ b/src/installation/index.md @@ -0,0 +1,11 @@ + + +# 開発環境の準備 + +**TODO** このページは書きかけです。 + +この章では、手元のパソコンに Rust の開発環境と、テキストエディタとして [Visual Studio Code](https://code.visualstudio.com/) をインストールする方法について説明します。 + +環境を手元に用意するメリットは普段使い慣れたエディタや環境でコーディングできるようになることです。開発環境を用意して Language Server Protocol に対応するエディタ ([Visual Studio Code](https://code.visualstudio.com/) など) を利用すれば、入力補完やリアルタイムのエラーチェックなど様々な機能の恩恵を受けることができます。逆に言うと、自分の使い慣れたエディタや環境を使いたいと思わずむしろ環境を整える方が面倒だと感じられる方は AtCoder のコードテスト (TODO: リンクが完成次第挿入) を利用するのが最も簡単な方法です。外部ライブラリにまつわる互換性の問題もありません。 + +既に Rust の開発環境がインストールされており、普段使い慣れたエディタや編集環境もあるという方には前半は全く不要な話となります。[`cargo-generate` のインストール](cargo-generate.md)へお進みください。それもインストールされている方はこの章で説明することはありませんので、実際に[参加方法の説明](../participate/index.md)へお進みください。 diff --git a/src/installation/rls.md b/src/installation/rls.md new file mode 100644 index 0000000..e8b10dd --- /dev/null +++ b/src/installation/rls.md @@ -0,0 +1,51 @@ + + +# Rust Language Server のインストール + +Rust Language Server (RLS) は、ソースコード編集中の様々な支援機能を提供するためのプログラムです。例えば、プログラムを編集しながらリアルタイムでエラー箇所をハイライトしたり、コード補完機能を提供したり、定義にジャンプしたり、簡単なドキュメントを表示したりといった様々な機能があります。使い慣れたエディタとともにこうした支援機能が使えることが、ローカルに Rust の環境を作る大きなメリットです。 + +なお、こうしたコーディング支援機能が不要だと考える方はインストールをする必要はありません。 + +> Note: Visual Studio Code を利用している方は、拡張機能が自動的にインストールしてくれるため、ここで直接インストールする必要はありません。 + +さて、 RLS は Rust 本体と同時に配布されているため、 RLS のインストールをする前に対応するバージョンの Rust をインストールしなければなりません。現在 AtCoder で使える Rust のバージョンは 1.42.0 ですので、コマンド プロンプトあるいは端末を開いて次のようにコマンドを実行します。 + +```console +$ rustup install 1.42.0 +info: syncing channel updates for '1.42.0-x86_64-pc-windows-msvc' +info: latest update on 2020-03-12, rust version 1.42.0 (b8cedc004 2020-03-09) +info: downloading component 'cargo' +info: downloading component 'clippy' +info: downloading component 'rust-docs' + 12.0 MiB / 12.0 MiB (100 %) 5.9 MiB/s in 1s ETA: 0s +info: downloading component 'rust-std' +info: downloading component 'rustc' + 35.6 MiB / 35.6 MiB (100 %) 28.2 MiB/s in 1s ETA: 0s +info: downloading component 'rustfmt' +info: installing component 'cargo' +info: installing component 'clippy' +info: installing component 'rust-docs' + 12.0 MiB / 12.0 MiB (100 %) 2.4 MiB/s in 4s ETA: 0s +info: installing component 'rust-std' +info: installing component 'rustc' + 35.6 MiB / 35.6 MiB (100 %) 10.7 MiB/s in 3s ETA: 0s +info: installing component 'rustfmt' + + 1.42.0-x86_64-pc-windows-msvc installed - rustc 1.42.0 (b8cedc004 2020-03-09) + +info: checking for self-updates +``` + +続けて RLS をインストールします。なお必要なコンポーネントは変わるかもしれませんので、適宜 [RLS のリポジトリ](https://github.com/rust-lang/rls)も参照してください。 + +```console +$ rustup component add --toolchain 1.42.0 rls rust-analysis rust-src +info: downloading component 'rls' +info: installing component 'rls' +info: downloading component 'rust-analysis' +info: installing component 'rust-analysis' +info: downloading component 'rust-src' +info: installing component 'rust-src' +``` + +両方の実行が完了すれば、 RLS のインストールは終了です。 diff --git a/src/installation/toolchain.md b/src/installation/toolchain.md new file mode 100644 index 0000000..d7a0126 --- /dev/null +++ b/src/installation/toolchain.md @@ -0,0 +1,53 @@ + + +# Rust ツールチェインのインストール + +**TODO** このページは書きかけです。 + +> Note: インストール方法は適宜変わる可能性があります。情報が古いまたは不足している場合は、公式の [book](https://doc.rust-lang.org/book/ch01-01-installation.html) にある解説を適宜参照ください (英語) 。 + +まずは Rust 本体をインストールする必要があります。 + + +## ステップ 1: Rust に必要になる依存関係を追加する + +OS によっては Rust を実行するのに追加のプログラムが必要になりますので、まずはそれをインストールしましょう。 + +- Windows + + (TODO: Visual Studio Build Tools をインストール) + +- macOS + + (TODO: Cコンパイラ (に付属するリンカー) のインストール) + +- Linux (Windows Subsystem for Linux を含む) + + (TODO: Cコンパイラ (に付属するリンカー) のインストール) + + +## ステップ 2: Rustup のインストールスクリプトを実行する + +OS によっては標準のパッケージ管理に Rust のパッケージが存在することもありますが、ここでは Rustup という Rust のバージョン管理プログラムを通してインストールすることを前提とします。このプログラムを使うと、最新版へのバージョンアップや特定のバージョンのインストールがコマンド一つで実行できます。また、そのようにしてインストールされた複数のバージョンの Rust を簡単に使い分けることができます。 + + にアクセスすると、お使いのプラットフォームに合わせてインストールスクリプトを実行する方法が表示されます。大きくは Windows と macOS/Linux で分かれます。 + +- Windows + + `rustup-init.exe` のような実行ファイルのダウンロードリンクが示されていると思いますので、それをダウンロードして実行します。 + +- macOS / Linux (Windows Subsystem for Linux 含む) + + `curl` を用いてスクリプトをダウンロード・実行する方法が示されていると思います。書かれているコマンドをターミナルへ入力してください。 + +(TODO: 以下、スクリプトの指示に従ってインストールする方法とインストールを確認する方法を書く) + + +## ステップ 3: インストールされたことを確認する + +インストール終了後、 Windows の方はコマンド プロンプト、 macOS または Linux の方は端末を開き、次のように入力してみましょう。次のようにバージョン情報が表示されればインストールは完了です。もしコマンドが見つからない、のようなエラーメッセージが表示される場合は、環境変数がまだ反映されていない可能性があります。一度再起動をして、もう一度試してみてください。 + +```console +$ rustc --version +rustc 1.42.0 (b8cedc004 2020-03-09) +``` diff --git a/src/introduction.md b/src/introduction.md index 298add9..8b082f9 100644 --- a/src/introduction.md +++ b/src/introduction.md @@ -2,8 +2,6 @@ # はじめに -**TODO** このページは書きかけです。 - 本書はAtCoderのコンテストにRustで参加するためのガイドブックです。 @@ -11,30 +9,33 @@ AtCoderは、オンラインで参加できるプログラミングコンテスト(競技プログラミング)のサイトです。リアルタイムのコンテストで競い合ったり、約3000問のコンテストの過去問にいつでも挑戦することが出来ます。 ([AtCoderのトップページ](https://atcoder.jp/)より引用) -**Note:** 競技プログラミングはプログラミングで解決できるような問題をなるべく早く正確に解く競技です。競技プログラミングについてよく知らないが興味があるという方は、インターネット上に初心者向けの詳しい情報がたくさんありますので検索してみてください。AtCoderで開催されているものでは、大きく分けて二種類あります。 - -- 与えられる問題に対して、その解を出力するようなプログラムを書く競技 (アルゴリズム系) - - 定期開催のもの: AtCoder Beginner Contest (ABC), AtCoder Regular Contest (ARC), AtCoder Grand Contest (AGC) があり、難易度は通常 ABC < ARC < AGC です。 - - 定期開催の他、企業によって開かれるコンテストもあります。そういったコンテストで上位成績をとると、その企業への就職、インターン、アルバイトなどで多少優遇されることがあります (コンテストによります) 。 - - 例: 「整数`N`が与えられます。`N`以下の正整数から等確率に1つを選ぶとき、それが奇数になる確率を求めなさい」 (AtCoder Beginner Contest 142 A問題) - - 例: 「`N`人の身長が与えられます。`K`cm以上の人の人数を出力してください」 (AtCoder Beginner Contest 142 B問題) -- 与えられる問題に対して、少しでも良い解を出力するようなプログラムを書く競技 (マラソン系) - - 定期開催のものはまだありません。企業が自社の取り組みやそこでの課題をテーマに出題することが多いようです。 - - 例: 「ある観測データが与えられるので、可能な限り圧縮するプログラムとそれを解凍するプログラムを書いてください」 (Wethernews Programming Competition) +> Note: 競技プログラミングはプログラミングで解決できるような問題をなるべく早く正確に解く競技です。競技プログラミングについてよく知らないが興味があるという方は、インターネット上に初心者向けの詳しい情報がたくさんありますので検索してみてください。AtCoderで開催されているものでは、大きく分けて二種類あります。 +> +> - 与えられる問題に対して、その解を出力するようなプログラムを書く競技 (アルゴリズム系) +> - 定期開催のもの: AtCoder Beginner Contest (ABC), AtCoder Regular Contest (ARC), AtCoder Grand Contest (AGC) があり、難易度は通常 ABC < ARC < AGC です。 +> - 定期開催の他、企業によって開かれるコンテストもあります。そういったコンテストで上位成績をとると、その企業への就職、インターン、アルバイトなどで多少優遇されることがあります (コンテストによります) 。 +> - 例: 「整数`N`が与えられます。`N`以下の正整数から等確率に1つを選ぶとき、それが奇数になる確率を求めなさい」 (AtCoder Beginner Contest 142 A問題) +> - 例: 「`N`人の身長が与えられます。`K`cm以上の人の人数を出力してください」 (AtCoder Beginner Contest 142 B問題) +> - 与えられる問題に対して、少しでも良い解を出力するようなプログラムを書く競技 (マラソン系) +> - 定期開催のものはまだありません。企業が自社の取り組みやそこでの課題をテーマに出題することが多いようです。 +> - 例: 「ある観測データが与えられるので、可能な限り圧縮するプログラムとそれを解凍するプログラムを書いてください」 (Wethernews Programming Competition) ## なぜRustなのか? AtCoderで使える言語は非常にたくさんあります。どの言語を使ってもよいですし、問題によって使い分けても構いません。その中でなぜRustを使うのか、そのメリットとデメリットをまとめてみました。できるだけ一般論で比較するよう心がけますが、競技プログラミングにおけるC++人口がそれなりに多いことと、Rustはその特性上C++と比較されることが多いので、具体的にC++との比較になっている部分も多くあります。 + ### メリット + #### 高速である AtCoder含め、競技プログラミングでは「実行時間制限」とよばれるものがあります。この時間内にプログラムの実行が終わらないと「TLE (Time Limit Exceeded)」という判定が付いて誤答扱いとなります。多くの場合は想定されている解法であれば多少の余裕をもって解けるように設定されていますが、非常にたくさんの言語が使える都合上全ての言語で公平になるようにはできません。遅い言語に合わせて設定すると速い言語では強引な解法でゴリ押しできてしまうことがありますし、速い言語に合わせると遅い言語では想定されている解法でも通せないということになります。いずれにせよ、基本的には速い言語であるほうが計算時間的には有利です。 (もちろん遅い言語と言われるものにも、例えば書き易さであったり、ライブラリが充実していたり、なにかしらのメリットがあるはずです。どちらかが絶対的に有利ということではありません。) Rustは最速と言われるC/C++並みに速いとされていますので、(少なくともAtCoderでは) 速度面で不利になることはないと言えるでしょう。 + #### 信頼性が高い 信頼性は、ここではRustの[公式トップページ](https://www.rust-lang.org/)に倣いメモリ安全性、スレッド安全性、バグの起こしにくさであるとします。競技プログラミングで特に大事になってくるのはメモリ安全性とバグの起こしにくさです。 @@ -99,6 +100,7 @@ stack backtrace: note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. ``` + #### 多くの問題をコンパイル時に発見できる RustはC/C++並みの速度を確保するため、実行時にやらなければいけないことをなるべく減らす方針の言語です。たとえば先ほど触れたように、多くの言語にあるガベージコレクタがありません。それだけならばC++と変わりありませんが、速度と安全性を両立させるためにRustではできるだけ多くのことをコンパイル時に確認する仕組みになっています。C++が受け入れてしまうような危険なコードもコンパイルエラーにします。 @@ -138,6 +140,7 @@ let x: i32 = s.into_iter().sum(); ジェネリクスとトレイトの仕組みも強力です。たとえばジェネリックな関数が型変数`T`をもつとき、この`T`のとりうる型を特定のトレイト (=機能一覧) を実装しているものだけに制限することができます。逆に`T`に対してできることはその特定のトレイトが定める機能のみです。従って、一度コンパイルが通った関数はその制約を満たす限りのどのような`T`を与えても関数の内部でコンパイルエラーとなることはありません。特にライブラリを整備するにあたってはこれはとてもありがたいことです。実際に使ってみなくても、コンパイルさえ通れば、将来的に作られうるどんなユーザー定義型を与えようともその関数が正しく呼び出せることが保証されます。C++のテンプレートなどでは実際に具体的な型を与えて始めて様々な検証をするので、使う段階になってからでないとエラーが発見できません。このことは、後述するコンパイルエラーの分かりやすさにも繋がっています。 + #### コンパイルエラーが分かりやすい これは少々主観的な話になるのかもしれませんが、Rustのコンパイルエラーは読みやすく分かりやすいという評判があります。実際にコンパイルエラーが発生したとき、まずエラーが起きた場所はもちろんとして、エラーが関連する他の場所 (例えば以前に借用された場所など) などをアスキーアート的な手法で視覚的に分かりやすく表示してくれます。さらに、なぜそれが間違っているのか/それをどのように修正することができるかのヒントが提示されることもあります。例えば、先ほどのエラー全体は次のようになっていました。 @@ -187,6 +190,7 @@ fn main() { (以下略) `````` + #### 抽象化のための機能を数多く備えている 例えば次のようなさまざまな機能があります。Rustは後発の言語ですので、他のプログラミング言語に備わっている優れた機能も参考にして多数の機能が導入されています。 @@ -270,6 +274,7 @@ fn main() { また、変数の個数を抑止するという効果もあります。block expression等と適宜組み合わせることで変数の数やスコープはさらに小さく保つことができ、多少関数の実装が長くなっても見通しが悪くなりにくいと言えます。競技プログラミングではmain関数が長くなりがちなので一層嬉しいのではないでしょうか。 + #### ゼロコスト抽象化を追求している Rustの言語デザインやライブラリは、一定の使いやすさを実現しつつも、使いやすさのために実行時の高速性を犠牲にはしないという**ゼロコスト抽象化** (_zero-cost abstraction_)を追求しています。 @@ -278,8 +283,10 @@ Rustの言語デザインやライブラリは、一定の使いやすさを実 このことは「簡潔な構文や関数によってその機能が必要とするコストを隠してしまう」ことを避けているとも言えます。つまり、本当にパフォーマンスが必要なときに最適化を検討するべき「コスト」の部分が明確化されているということでもあります。 + ### デメリット + #### 現れる概念が比較的難しい 先に見たように、Rustでは、いままで他の言語ではコンパイラが検証していなかったようなことをコンパイル時に検証します。そのためにRustでは所有権や借用をはじめとする独特の概念が導入されており、それらの概念の理解そのものが難しいとされることも多いようです。これらの概念が課す多数のルールがなぜ存在するのかを理解することは、仕組みをある程度理解していなければ難しいものです。 @@ -288,6 +295,7 @@ Rustの言語デザインやライブラリは、一定の使いやすさを実 Rustが課すルールにも理由がありますので、そういった事情について意識的に考えることは他の言語や競技プログラミング以外の文脈でも活きる有意義なものではあると思います。単にAtCoderである程度の競技プログラミングをするだけであれば、C#やJavaといった言語でもほぼ正解できるよう調整されているようなので、どちらを取るかは好みといっていいかもしれません。 + #### 素早く書くことにはあまり向かない仕様 Rustの安全指向や標準ライブラリの設計方針などは、時間をかけて大規模なプログラムを書くときや堅牢なプログラムを書くときには非常に役に立ちます。一方で競技プログラミングでは、一般のプログラミングと異なり、次のような特徴があります。 @@ -326,7 +334,7 @@ fn main() { 例えば[`Index`](https://doc.rust-lang.org/stable/std/ops/trait.Index.html)で境界外アクセスしたときやメモリが足りずにアロケーションに失敗したとき、[`println!`が失敗したとき](https://doc.rust-lang.org/std/macro.println.html#panics)にパニックします。 このように「失敗するとパニックする」ものはその条件をドキュメントに`# Panics`という形で書いています。 -(TODO: proconioの当落に応じて追記) +> Note: 入力をとる方法については、2020年言語アップデートで外部クレートとして[`proconio`](https://docs.rs/proconio/0.3.6/proconio/)や[`text_io`](https://docs.rs/text_io/0.1.8/text_io/), [`whiteread`](https://docs.rs/whiteread/0.5.0/whiteread/)などのクレートが導入されたため、かなり改善されました。リンク先はそれぞれのクレートのドキュメントになっていますので、詳しくはそちらをご覧ください。 他にも、先程少し触れましたが例えば数値型の四則演算や比較を行なうときには基本的に両辺の型が等しくなければいけません。 `i32`と`&'_ i32`を両辺に持って来ることくらいは許されていますが`i32`と`i64`をそのまま足したり比較したりはできません。 @@ -343,11 +351,12 @@ fn main() { Rustで参加する競技プログラマーの中には、こうした煩雑さを改善するためのマクロやヘルパ関数 (もっと便利に標準入力がとれるようにするなど) を定義し、テンプレート (ひな型) として用意している方もいます。インターネット上で公開されている方もいらっしゃいますし、過去のコンテストでの上位Rust参加者の提出などをのぞいてみると、いろいろと参考になるかもしれません。 + #### 標準ライブラリが小さい Rustは比較的新しい言語ですので、インターネット接続環境を前提にしたパッケージ管理システムCargoを標準で持ちます。このため、言語の成長とクレートやRustエコシステムの成長を分離することを目的に、Rustは標準ライブラリを最低限の抽象化とインターフェースとして位置付け、できるだけ小さく保ち続けてきました。かつて標準ライブラリの一部だったり本体にバンドルされていたライブラリ (`num`, `rand`, `regex` など) を積極的に分離することさえしています。ユーザーはCargoを使えば、使いたいパッケージを[crates.io](https://crates.io)からいつでも自由にダウンロードできます。 -(TODO: クレートが導入されたかどうか追記) +しかし、逆に言えば標準ライブラリだけでは使える機能が非常に制限されるということにもなります。そのため、2020年言語アップデートでいくつかの著名な外部クレートが導入されて利用できるようになりました。2020年4月6日現在、利用可能なクレートの一覧とそれぞれについての簡単な説明が[こちら](https://github.com/rust-lang-ja/atcoder-rust-resources/wiki/2020-Update)にまとめられています。 #### コンパイル時間が長くなりがち diff --git a/src/participate/before-contest/choose-crates.md b/src/participate/before-contest/choose-crates.md new file mode 100644 index 0000000..e589f33 --- /dev/null +++ b/src/participate/before-contest/choose-crates.md @@ -0,0 +1,74 @@ + + +# 利用するクレートの選択とコンパイル + +**TODO** このページは書きかけです。 + +先にも軽く触れた通り、依存クレートのコンパイルにはそれなりの時間がかかります。コンテストが始まってから最初の問題の提出前に実行するとなるとそれなりのタイムロスになります。そこで次の二つのことをコンテスト開始前に行ってしまい、コンテスト開始後になるべくスムーズに行動できるよう準備しておきましょう。 + + +## 利用するクレートの選択 + +これは事前準備時間を短くする、またはビルドディレクトリのディスク容量を減らすことに効果があります。 + +すべての依存クレートを有効化すると、スペックや環境にもよりますが、初回のコンパイルに数分かかるようになり、ビルドキャッシュも数百 MB (メガバイト) になります。ただし二回目以降のコンパイル時間やコンパイル後のバイナリの実行速度には影響しません。すなわち、競プロとして AtCoder 上で不利になるようなことはありません。したがって、最初にすべてのクレートを有効にしてしまったほうがコンテスト中の自由度は高くなります。このあたりのバランスはご自分のパソコンのリソースと相談して選択してください。 + + +## 事前コンパイル + +利用するクレートの選択を終えたら、次は事前コンパイルを行います。 + +(TODO: コマンド プロンプトまたは端末を開き、プロジェクトのあるフォルダまで移動する方法を説明する) + +端末を開いてプロジェクトのあるフォルダまで移動したら、次のようにビルドを行います。 + +```console +$ cargo build + Updating crates.io index + Compiling proc-macro2 v0.4.30 + Compiling unicode-xid v0.1.0 + Compiling syn v0.15.39 + Compiling lazy_static v1.3.0 + Compiling quote v0.6.12 + : + : + Finished dev [unoptimized + debuginfo] target(s) in 20.27s +``` + +`Finished` の文字が見えたら、依存クレートのコンパイルは完了となります。 + +> Note: ここでは `cargo build` としてデバッグモードでのビルドを行いました。実際の AtCoder では `--release` オプションをつけて実行速度を最適化するのですが、これをつけるとさらにビルド時間が伸びてしまうことや、デバッガによるデバッグがしづらくなることなどのデメリットがあります。加えて、手元の環境ですることはサンプルケースレベルの比較的小さいサイズの入力を試す程度であることが多いため、速度を最適化する必要性もさほどないことが多いのではないでしょうか。一方、手元でもリリースビルドでテストすることがあるという方は、この段階で `cargo build --release` も加えて実行しておくことをおすすめします。そうでないとコンテスト中にリリースビルド用の依存クレートのコンパイルが行われ、多くの時間を取られてしまいます。 + + +## (オプション) Rust Language Server の事前準備 + +> Note: この手順は Rust Language Server (RLS) を利用しない方は必要ありません。 + +RLS は `cargo build` とは別にキャッシュを持っており、初回起動時にキャッシュを作成します。したがって今の状態のプロジェクトは `cargo build` については十分高速に実行できますが、プロジェクトを開いてから補完などが機能するまでには時間がかかってしまうということです。したがって、このキャッシュについても今のうちに作っておくと、開いた直後から快適な編集ができます。 + + +> Note: 最近は RLS の後継 (RLS 2) として開発されている Rust Analyzer という Language Server もあります。 [GitHub のリポジトリ](https://github.com/rust-analyzer/rust-analyzer)によればまだ開発段階とのことですが、以前に比べ機能も揃ってきています。不具合や課題もまだまだあるとはいえ、特にレスポンス面では Rust Language Server を超えている部分も多く見られます。この説明では正式版の RLS を採用しますが、導入方法もだんだんと整備されて簡単になっていますので、興味のある方はぜひお試しください。Visual Studio Code であれば拡張機能を一つインストールするだけです。 + +実際にキャッシュを作る方法は、単に今作成したプロジェクトを開くだけです。以下では Visual Studio Code の場合に説明しますが、他のエディタを利用する場合はそれに合わせて行ってください。 + +- プロジェクトを開きます。 + + もし対応するバージョンの RLS がインストールされていない場合は、次のようなダイアログが右下に表示されます。ここで Yes を選択すれば自動的に RLS がインストールされます。 + + ![RLS is not installed. Install?](rls_install_prompt.png) + +- ステータスバー左側の様子をチェックします。 + + 開いた当初は、くるくる回るインジケーターとともに Starting と表示されています。 + + ![RLS Starting](rls_starting.png) + + しばらくするとくるくる回りながらビルドが始まります。右側には現在ビルドしているクレートが表示されます。 + + ![RLS Building](rls_building.png) + + それが終わると、くるくる回るインジケーターが消えて RLS とだけ表示される状態になります。 + + ![RLS](rls_finish.png) + + この状態になれば RLS の準備は完了です。 diff --git a/src/participate/before-contest/copy-project.md b/src/participate/before-contest/copy-project.md new file mode 100644 index 0000000..7adc06f --- /dev/null +++ b/src/participate/before-contest/copy-project.md @@ -0,0 +1,21 @@ + + +# プロジェクトのコピー + +**TODO** このページは書きかけです。 + +競プロで書くコードは書き捨てにする、という方は先程作ったプロジェクトをすべての問題で使いまわしても問題ありませんが、コードをずっと残しておきたいとか、あるいは詰まったから一旦保存しておいて別の問題に行きたいことがよくある、といった事情で、プロジェクトを予め問題数分用意しておきたい方もいるかと思われます。この作業も少々手間ですので、このようにされたい方はコンテスト前に準備しておくとよいでしょう。 + +もっとも簡単で確実なのは、プロジェクトをそのまままるごとコピーすることです。容量に不安のない方はそれで構いません。しかし数百 MB に及ぶプロジェクトをそのままコピーすることは時間も負担もかかりますし、リソース的に難しいという方もいると思います。多くの容量を占めるのは `target/` 以下であり、しかもほとんどは全く同一のビルドキャッシュになります。そこでこの `target` フォルダをシンボリックリンクにしてしまい、実体は一つにしてしまうという手があります。 (TODO: Linux と macOS での動作確認をする) + +方法は、コピーするときに `target` フォルダだけ除外してコピーしておき、コピーされた各プロジェクトの中に、先に除外した `target/` フォルダを指すようなシンボリックリンク (Windows の場合、ジャンクションでも構いません) を作成します。 + +- Windows + + (TODO: ジャンクション (`mklink /J target /path/to/original/target`) または (必要ならローカルセキュリティポリシーまたはレジストリエディタを使って SeCreateSymbolicLinkPrivilege 権限を有効にして) シンボリックリンク (`mklink /D target /path/to/original/target`)) + +- macOS または Linux + + (TODO: `ln -s /path/to/original/target target`) + +ただし、このときはメインバイナリ `target/debug/` すらも共有になってしまうため、別のプロジェクトを `cargo run` する前に `cargo clean -p ` としてバイナリを削除する必要があります。 `cargo` はおそらくソースファイルとバイナリの更新日時を比較してリビルドの要不要を判断しているため、状態によっては前のプロジェクトの成果物をそのまま実行してしまうことがあります。 diff --git a/src/participate/before-contest/generate-project.md b/src/participate/before-contest/generate-project.md new file mode 100644 index 0000000..6f33fcd --- /dev/null +++ b/src/participate/before-contest/generate-project.md @@ -0,0 +1,43 @@ + + +# プロジェクトを生成する + +**TODO** このページは書きかけです。 + +まずは AtCoder サーバーと同じ環境のプロジェクトを手元に準備します。 + +まずは、今から参加するコンテストのソースコードを置くフォルダを準備してください。 + +(TODO: フォルダを作成してそこに cd する方法を説明する) + +では、実際にプロジェクトを生成していきます。 + + +## `cargo-generate` をインストールしている場合 + +`cargo generate` コマンドをインストールしている場合は、次のようにコマンドを実行してプロジェクト名を入力すれば AtCoder での環境と同様の環境のプロジェクトが生成できます。 + +```console +$ 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 /path/to/project/abc000 +``` + +これで表示されているパスにプロジェクトが生成されました。 + +> Note: ここで生成されるプロジェクトはサンプルとして [AtCoder Beginner Contest 086 C - Traveling](https://atcoder.jp/contests/abc086/tasks/arc089_a) の解答例とサンプルケースのテスト方法例が書かれてます。テンプレートを自分向けにカスタマイズしたい場合は、リポジトリをフォークするなどして編集し、それを URL に指定して生成させることもできます。 + + +## `cargo-generate` をインストールしていない場合 + +まずは空のプロジェクトを作成します。 + +``` +$ cargo init abc000 + Created binary (application) package +``` + +そして `abc000/Cargo.toml` の `[dependencies]` 以下に AtCoder で利用できるライブラリを追加してください。 [atcoder-rust-base](https://github.com/rust-lang-ja/atcoder-rust-base) の [ja ブランチ](https://github.com/rust-lang-ja/atcoder-rust-base/tree/ja) に含まれている Cargo.toml の雛形を参考にできます。ただしこれは `cargo-generate` 用の雛形のためプロジェクト名など一部の項目がプレースホルダになっており、そのまま使えるものではないことに注意が必要です。もし完全な形の Cargo.toml をお探しなら、 [ja-all-enabled ブランチ](https://github.com/rust-lang-ja/atcoder-rust-base/tree/ja-all-enabled) に有効な形の Cargo.toml が含まれていますので、こちらを利用することもできます。 + +また、 Rustup を利用している場合、プロジェクトディレクトリに `rust-toolchain` というファイルを置いて中身に `1.42.0` とだけ書いておくと、 `cargo` などのツールを呼び出したときに自動的に Rust 1.42.0 のツールチェインを利用してくれます。もしそのツールチェインがインストールされていなければ自動でダウンロードが始まり、インストールされます。この先しばらくして Rust のバージョンアップが進み、再び AtCoder 側のバージョンとの乖離が大きくなってきたときは、間違って 1.43 以降にしか存在しない機能を利用してしまって Compilation Error を受けないためにも強制的に 1.42.0 を利用させるのが便利です。 diff --git a/src/participate/before-contest/index.md b/src/participate/before-contest/index.md new file mode 100644 index 0000000..a303668 --- /dev/null +++ b/src/participate/before-contest/index.md @@ -0,0 +1,10 @@ + + +# コンテスト開始前の事前準備 + +コンテストの開始前にプロジェクトを準備して一度ビルドしておくと、コンテスト開始後の動きがスムーズになります。特に初回ビルド時は依存クレートのコンパイルに時間がかかります。お使いのパソコンのスペックにもよりますが、もしすべてのクレートを有効にした場合は完了まで数分程度かかるとお考えください。 + +1. 作業するためのプロジェクトを作成します。 +1. 使いそうなクレートを有効化し、一度プロジェクトをビルドしておきます。 +1. プロジェクトを問題数分だけコピーしておきます。 + - 好みに応じて一つのプロジェクトを使い回すのでもかまいません。 diff --git a/src/participate/before-contest/rls_building.png b/src/participate/before-contest/rls_building.png new file mode 100644 index 0000000..3422498 Binary files /dev/null and b/src/participate/before-contest/rls_building.png differ diff --git a/src/participate/before-contest/rls_finish.png b/src/participate/before-contest/rls_finish.png new file mode 100644 index 0000000..9bc72a5 Binary files /dev/null and b/src/participate/before-contest/rls_finish.png differ diff --git a/src/participate/before-contest/rls_install_prompt.png b/src/participate/before-contest/rls_install_prompt.png new file mode 100644 index 0000000..0337c36 Binary files /dev/null and b/src/participate/before-contest/rls_install_prompt.png differ diff --git a/src/participate/before-contest/rls_starting.png b/src/participate/before-contest/rls_starting.png new file mode 100644 index 0000000..ca69866 Binary files /dev/null and b/src/participate/before-contest/rls_starting.png differ diff --git a/src/participate/during-contest/index.md b/src/participate/during-contest/index.md new file mode 100644 index 0000000..4631789 --- /dev/null +++ b/src/participate/during-contest/index.md @@ -0,0 +1,8 @@ + + +# コンテスト開始後の流れ + +1. 問題を開き、テストケースを記述します。 +1. プログラムを書きます。 +1. テストします。 +1. プログラムを提出します。 diff --git a/src/participate/during-contest/std-doc-version.png b/src/participate/during-contest/std-doc-version.png new file mode 100644 index 0000000..f3bb53b Binary files /dev/null and b/src/participate/during-contest/std-doc-version.png differ diff --git a/src/participate/during-contest/submit.md b/src/participate/during-contest/submit.md new file mode 100644 index 0000000..18b09e6 --- /dev/null +++ b/src/participate/during-contest/submit.md @@ -0,0 +1,7 @@ + + +# プログラムの提出 + +**TODO** このページは書きかけです。 + +テストも終わって問題ないとなれば、最後は提出です。書いたコードをコピーして、コンテストページから提出し、結果を確認してください。 `AC` ならば正解で、 `WA` ならば不正解です。サンプルが通るのに `WA` になった場合は、考慮漏れや他のバグがないか確認してみましょう。 diff --git a/src/participate/during-contest/test.md b/src/participate/during-contest/test.md new file mode 100644 index 0000000..be8f58f --- /dev/null +++ b/src/participate/during-contest/test.md @@ -0,0 +1,71 @@ + + +# プログラムのテスト + +一通り書き終わったと思ったら、提出前にまずは一度サンプルケースで答えが合うかどうかを確認してみましょう。コマンド プロンプトまたは端末を開いてプロジェクトフォルダに移動して、次のようなコマンドを実行します。 + +```console +$ cargo test + Compiling abc000 v0.1.0 (C:\Users\dicen\workspace\daily\2020\0406\abc000) + Finished dev [unoptimized + debuginfo] target(s) in 0.52s + Running target\debug\deps\main-1ecbd097f851d76e.exe + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Running target\debug\deps\sample_inputs-05a0de7d755e5cc1.exe + +running 3 tests +No +test sample3 ... ok +Yes +test sample1 ... ok +No +test sample2 ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +``` + +すると、このようにテスト結果が表示されます。このように最後に `test result: ok.` となっていれば、すべてのテストに成功しているということになります。一方で、もし成功しないテストがあれば、次のようになります。 + +```console +$ cargo test + Compiling abc000 v0.1.0 (C:\Users\dicen\workspace\daily\2020\0406\abc000) + Finished dev [unoptimized + debuginfo] target(s) in 0.68s + Running target\debug\deps\main-1ecbd097f851d76e.exe + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Running target\debug\deps\sample_inputs-05a0de7d755e5cc1.exe + +running 3 tests +No +test sample2 ... ok +Yes +No +test sample1 ... FAILED +test sample3 ... ok + +failures: + +---- sample1 stdout ---- +thread 'sample1' panicked at 'assertion failed: `(left == right)` + left: `"Yes\n"`, + right: `"No\n"`', tests\sample_inputs.rs:16:5 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. + + +failures: + sample1 + +test result: FAILED. 2 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out + +error: test failed, to rerun pass '--test sample_inputs' +``` + +最後の `test result: FAILED.` により失敗したことが示されています。その横には成功と失敗の個数が示されています。そして上には失敗したときのコマンドの出力も示されています。 `assertion failed` 以降から、 `No` と出力すべきところを `Yes` と出力してしまったことがわかります。 + +> Note: メッセージに示される `left:` と `right:` はマクロ `assert_eq!(left, right);` に渡される引数の左右です。用意したテストコードでは実際の出力を左、期待される出力を右として `assert_eq!(output.stdout_str(), "No\n");` としていたことから、本来は `No` と出力すべきところを `Yes` と表示した、ということがわかります。 diff --git a/src/participate/during-contest/write-program.md b/src/participate/during-contest/write-program.md new file mode 100644 index 0000000..259b3bb --- /dev/null +++ b/src/participate/during-contest/write-program.md @@ -0,0 +1,15 @@ + + +# プログラムの作成 + +**TODO** このページは書きかけです。 + +テストが用意できたらプログラムを作成します。エディタを開いて思う通りにコードを書きましょう。 + +ちなみに、 AtCoder のコンテストでは、一部の例外的なコンテストを除いて、例え類題検索のようなことであっても、コンテスト中に自由にインターネットを検索・閲覧してよいことになっています。 + +> Note: このことは厳密には各コンテストごとのルール (例えば [AtCoder Beginner Contest 160](https://atcoder.jp/contests/abc160) であれば[こちら](https://atcoder.jp/contests/abc160/rules)) に記されています。 + +したがって、コンテスト中に[標準ライブラリのドキュメント](https://doc.rust-lang.org/std/index.html)やその他の外部クレートのドキュメント、使い方やサンプルコードなどを検索することは問題ありません。たとえば `itertools` にこういうメソッドなかったかなと思うことがあれば、遠慮なく Google で "itertools rust" などと検索してみましょう。大抵はそれでドキュメントが見つかるはずです。 + +(TODO: コンテスト中に特に有用なページがあればまとめたい) diff --git a/src/participate/during-contest/write-tests.md b/src/participate/during-contest/write-tests.md new file mode 100644 index 0000000..2517fe7 --- /dev/null +++ b/src/participate/during-contest/write-tests.md @@ -0,0 +1,65 @@ + + +# テストケースの作成 + +Rust には組み込みでテストをするための機構が備わっています。これらの様式に則ってテストを書くと、 `cargo test` コマンドを実行するだけでテストを実行することができます。これを競プロでもサンプルケースが通るかどうかを確かめるのに利用することができます。この機能の使い方の例として、生成したテンプレートの `tests/sample_inputs.rs` には [AtCoder Beginner Contest 086 C - Traveling](https://atcoder.jp/contests/abc086/tasks/arc089_a) のサンプルケースが書かれています。 + +> Note: 直接手と目で確認する場合や、別のコンテスト支援ツールを利用する場合などはこの手順は必要ありません。また `cargo test` を利用しない場合、サンプルのテストファイルは削除しても良いですし、しなくても特に問題はありません。 + +なんとなく見れば分かるように、 `output_with_stdin()` の引数にサンプル入力を渡し `assert_eq!(output.stdout_str(), );` で期待する出力と一致するかどうかを確かめます。一致しない場合、テストは失敗します。 + +```rust +use cli_test_dir::*; + +const BIN: &'static str = "./main"; + +#[test] +fn sample1() { + let testdir = TestDir::new(BIN, ""); + let output = testdir + .cmd() + .output_with_stdin(r#"2 +3 1 2 +6 1 1 +"#) + .tee_output() + .expect_success(); + assert_eq!(output.stdout_str(), "Yes\n"); + assert!(output.stderr_str().is_empty()); +} + +#[test] +fn sample2() { + let testdir = TestDir::new(BIN, ""); + let output = testdir + .cmd() + .output_with_stdin(r#"1 +2 100 100 +"#) + .tee_output() + .expect_success(); + assert_eq!(output.stdout_str(), "No\n"); + assert!(output.stderr_str().is_empty()); +} + +#[test] +fn sample3() { + let testdir = TestDir::new(BIN, ""); + let output = testdir + .cmd() + .output_with_stdin(r#"2 +5 1 1 +100 1 1 +"#) + .tee_output() + .expect_success(); + assert_eq!(output.stdout_str(), "No\n"); + assert!(output.stderr_str().is_empty()); +} +``` + +標準入力を書く場合、通常のダブルクオートでも改行を含めることはできますが、特別な文字 (`\` や `"` など) を含む場合に備えて、サンプルのように `r#"........"#` のような形式を使うとよいかもしれません。 + +> Note: `r"..."` は基本的には普通の文字列ですが、文字列内の `\` をエスケープしません。また `"` そのものを含めたいときに備えて `r####"...."####` のように `#` を任意個挟むことができます。 + +なお、この方法では出力を単純に文字列同士の比較によって判定しています。浮動小数点数のように出力に誤差を認める形式や「グラフを一つ出力せよ」のように解が複数あり得る問題のテストにはそのままでは利用できません。それでもテストには任意のコードがかけるわけですから (実際にそこまでするかどうかは別としても) 浮動小数点数やグラフをパースしてチェックするというような使い方も可能です。 diff --git a/src/participate/index.md b/src/participate/index.md new file mode 100644 index 0000000..b8c218b --- /dev/null +++ b/src/participate/index.md @@ -0,0 +1,9 @@ + + +# コンテストの参加方法 + +**TODO** この章は書きかけです。 + +本章では、手元にAtCoderのジャッジサーバーの環境と同等のプロジェクトを用意してコンテストに参加する方法について説明します。 + +ここでは、現在AtCoderで提供されている環境と同じ環境を使って手元でもコーディングできるようにするための最低限の汎用的な方法をなるべく標準的な方法で解説しています。実は、より競プロやAtCoderへの参加に特化したツールというものもあり、インターネットを検索するといくつも見つけることができます。これらのツールには、テストケースをAtCoderから自動でダウンロードしてテストしたり、自作ライブラリを自動で埋め込んで提出できる形に整形したり、そのツールから直接提出できたりするようなものも存在します。ここではそういったツールのご紹介はしませんが、競プロに慣れ、本格的に取り組んでみようと考え始めるようになれば一度検討してみるのもよいかもしれません。もちろん既存のツールを使わずに、自分にとって最も参加しやすいスタイルを新しく確立するのも面白いことです。 diff --git a/src/tips.md b/src/tips.md new file mode 100644 index 0000000..f677732 --- /dev/null +++ b/src/tips.md @@ -0,0 +1,5 @@ + + +# Tips(小技集) + +**TODO** このページは書きかけです。 diff --git a/src/todo.md b/src/todo.md deleted file mode 100644 index dc599af..0000000 --- a/src/todo.md +++ /dev/null @@ -1,5 +0,0 @@ - - -# TODO - -このページは未作成です。 diff --git a/src/use-crates.md b/src/use-crates.md new file mode 100644 index 0000000..f46b8d0 --- /dev/null +++ b/src/use-crates.md @@ -0,0 +1,5 @@ + + +# クレートの使用例 + +外部クレートの使用例については [2020 Update](https://github.com/rust-lang-ja/atcoder-rust-resources/wiki/2020-Update) のページに具体的なソースコードと一緒にまとまっています。