競技プログラミングにおけるPythonとRustの対応関係まとめ


# はじめに

競技プログラミングにおいてPythonでよく使用する関数やクラスについて、それらとRustのメソッドやデータ構造との対応をまとめました。
競技プログラミングでPythonからRustへ移行しようとしている人の参考になれば幸いです。

なお、本記事のRustのバージョンは1.15.1を想定しています(2019/09/07時点でのAtCoderのRustのバージョン)。

# 標準入出力

## 標準入力

Rustでは `std::io::Stdin` の[read_line](https://doc.rust-lang.org/beta/std/io/struct.Stdin.html#method.read_line)メソッドを用いて標準入力を1行単位で受け取ることができます（これはPythonのinput関数と同じですね）。
標準入力のパターンに応じて、受け取った文字列をsplitしたりparseしたりします。
Pythonと比べて、全体にしんどいのでスニペット／テンプレート化しておくとよいでしょう。
なお、高速に標準入力したい場合、StdinLock構造体を使うとよいようです。
参考: [Rust の標準入出力は(何も考えないで使うと)遅い - Qiita](https://qiita.com/tubo28/items/41eeb0dfa1ebbccb1ddc)

ideoneでの実行結果

* [Python](https://ideone.com/OoB3tU)
* [Rust](http://ideone.com/avhbrw)

### 単一の整数を標準入力する

例: 標準入力から単一の整数を受け取り、 `n` に束縛する。

```python:Python
n = int(input())
```

```rust:Rust
let n: i64 = {
    let mut line: String = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    line.trim().parse().unwrap()
};
```

### 単一の文字列を標準入力する

例: 標準入力から単一の文字列を受け取り、 `s` に束縛する。

```python:Python
s = input()
```

```rust:Rust
let s: Vec<char> = {
    let mut line: String = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    line.trim().chars().collect()
};
```

Rustでは、文字のVecとして `s` に文字列を束縛しています（イテレートする際に便利なので）。

### 定数個の整数を標準入力する

例: 標準入力から空白区切りで3個の整数を受け取り、 それぞれ `a`, `b`, `c` に束縛する。

```python:Python
a, b, c = map(int, input().split())
```

```rust:Rust
let (a, b, c): (i64, i64, i64) = {
    let mut line: String = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    let mut iter = line.split_whitespace();
    (
        iter.next().unwrap().parse().unwrap(),
        iter.next().unwrap().parse().unwrap(),
        iter.next().unwrap().parse().unwrap()
    )
};
```

整数の個数が3でない場合、Rustコードの右辺の `iter.next().unwrap().parse().unwrap()` の個数を整数の個数に合わせる必要があります。

### 可変個の整数（空白区切り）を標準入力する

例: 標準入力から空白区切りの整数のリストを受け取り、 `xs` に束縛する。

```python:Python
xs = list(map(int, input().split()))
```

```rust:Rust
let xs: Vec<i64> = {
    let mut line: String = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    line.split_whitespace()
        .map(|x| x.parse().unwrap())
        .collect()
};
```

### n個の整数（改行区切り）を標準入力する

例: 標準入力から改行区切りの `n` 個の整数のリストを受け取り、 `ys` に束縛する。

```python:Python
ys = [int(input()) for _ in range(n)]
```

```rust:Rust
let ys: Vec<i64> = (0..n)
    .map(|_| {
            let mut line: String = String::new();
            std::io::stdin().read_line(&mut line).unwrap();
            line.trim().parse().unwrap()
    })
    .collect();
```

### n行の定数個の整数を標準入力する

例: 標準入力からn行の整数ペアを受け取り、 `pairs` に（タプルのリストとして）束縛する。

```python:Python
pairs = [tuple(map(int, input().split())) for _ in range(n)]
```

```rust:Rust
let pairs: Vec<(i64, i64)> = (0..n)
    .map(|_| {
        let mut line: String = String::new();
        std::io::stdin().read_line(&mut line).unwrap();
        let mut iter = line.split_whitespace();
        (
            iter.next().unwrap().parse().unwrap(),
            iter.next().unwrap().parse().unwrap()
        )
    })
    .collect();
```

整数の個数が2でない場合、Rustコードの右辺の `iter.next().unwrap().parse().unwrap()` の個数を整数の個数に合わせる必要があります。

### 整数の二次元リストを標準入力する

例: 標準入力から二次元整数リストを受け取り、 `mat` に（リストのリストとして）束縛する。

```python:Python
mat = [list(map(int, input().split())) for _ in range(n)]
```

```rust:Rust
let mat: Vec<Vec<i64>> = (0..n)
    .map(|_| {
        let mut line: String = String::new();
        std::io::stdin().read_line(&mut line).unwrap();
        line.split_whitespace()
            .map(|x| x.parse().unwrap())
            .collect()
    })
    .collect();
```

Python, Rust ともにi行目j列目の要素には `mat[i][j]` でアクセスできます。

## 標準出力

Rustでは[println](https://doc.rust-lang.org/std/macro.println.html)マクロを用いて標準出力します。

ideoneでの実行結果

* [Python](http://ideone.com/HU4R0f)
* [Rust](http://ideone.com/EjtUY8)

### 単一の整数／文字列を標準出力する

例1: 整数 `x` を標準出力する（末尾に改行文字を含む）。

```python:Python
print(x)
```

```rust:Rust
println!("{}", x);
```

例2: 文字列 `s` を標準出力する（末尾に改行文字を含む）。

```python:Python
print(s)
```

```rust:Rust
println!("{}", s);
```

Rustの `s` は `String` または `&str` 型とします。
整数の場合と同一の文です。

### 文字リストを連結して標準出力する

例: 文字リスト `char_list` の各文字を連結した文字列を標準出力する（末尾に改行文字を含む）。

```python:Python
print(''.join(char_list))
```

```rust:Rust
println!("{}", char_list.iter().collect::<String>());
```

Rustの `char_list` は `Vec<char>` 型とします。

### 定数個の整数／文字列を標準出力する

例: 整数 `x`, `y`, `z` を空白区切りで標準出力する（末尾に改行文字を含む）。

```python:Python
print(x, y, z)
```

```rust:Rust
println!("{} {} {}", x, y, z);
```

`println!` の文字列フォーマットを利用します。 文字列を標準出力する場合も同様です。

### n個の整数／文字列を空白区切りで標準出力する

例: 整数のリスト `xs` を空白区切りで標準出力する（末尾に改行文字を含む）。

```python:Python
print(*xs)
```

```rust:Rust
println!(
    "{}",
    xs.iter()
        .map(std::string::ToString::to_string)
        .collect::<Vec<_>>()
        .join(" ")
);
```

`.map(std::string::ToString::to_string)` は `.map(|&x| x.to_string())` でも構いません。
`xs` の要素が文字列ならば `.map(std::string::ToString::to_string)` は不要です。

### n個の整数／文字列を改行白区切りで標準出力する

例: 整数のリスト `xs` を改行区切りで標準出力する（最終行末尾に改行文字を含む）。

```python:Python
print('\n'.join(map(str, xs)))
```

```rust:Rust
println!(
    "{}",
    xs.iter()
        .map(std::string::ToString::to_string)
        .collect::<Vec<_>>()
        .join("\n")
);
```

forループで `println!` をn回呼んでもよいでしょう（ただし、nが大きい場合、実行時間はおよそ10倍になります。この差はPyPyと比べて顕著なので注意してください）。

# データ構造

## list

Rustでは[std::vec::Vec](https://doc.rust-lang.org/std/vec/struct.Vec.html)をlistして使う方法を紹介します。

ideoneでの実行結果

* [Python](http://ideone.com/GiBGZy)
* [Rust](http://ideone.com/yozZJI)

### listを生成する

例1: 3, 3, 4を要素とするlist `a` を生成する。

```python:Python
a = [3, 3, 4]
```

```rust:Rust
let mut a = vec![3, 3, 4];
```

`a` に対して破壊的操作を行わない場合、 `mut` は不要です。

例2: 0以上10以下の偶数を2乗したlist `b` を生成する。

```python:Python
b = [i**2 for i in range(10 + 1) if i % 2 == 0]
```

```rust:Rust
let mut b: Vec<_> = (0..(10_i64 + 1))
    .filter(|&i| i % 2 == 0)
    .map(|i| i.pow(2))
    .collect();
```

残念ながらRustではリストの内包表記は使えません（サードパーティの [cute](https://docs.rs/cute/0.3.0/cute/) を使うとリストの内包表記のような記法でvecを作成できるようですが）。

例3: 空のlist `c` を作成する。

```python:Python
c = []
```

```rust:Rust
let mut empty_list = vec![];
```

### listの要素数を求める

例: list `a` の要素数を `cardinality` に束縛する。

```python:Python
cardinality = len(a)
```

```rust:Rust
let cardinality = a.len();
```

### listのi番目の要素を求める

例: list `a` の2番目(0-indexed)の要素を `second_element` に束縛する。

```python:Python
second_element = a[2]
```

```rust:Rust
let second_element = a[2];
```

### listをイテレートする

例: list `a` の要素を先頭から順に1行ずつ標準出力する。

```python:Python
for x in a:
    print(x)
```

```rust:Rust
for &x in &a {
    println!("{}", x);
}
```

Rustのコードの `a` は `Vec<i64>` 型とします。
Rust で `for x in a` と書いた場合、所有権が移動してしまい、以降 `a` を参照できないので注意してください。
また、 `for x in &a` と書いた場合、 `x` には `a` の要素への参照が束縛されることに注意してください（`a` の要素がプリミティブでないならば、参照を束縛させることになります）。

### listに含まれる指定した要素の個数を求める

例: list `a` に含まれる3の個数を `num_of_three` に束縛する。

```python:Python
num_of_three = a.count(3)
```

```rust:Rust
let num_of_three = a.iter()
    .filter(|&&x| x == 3)
    .count();
```

Rustだと少々面倒です。
とはいえ、指定した述語にマッチする要素の個数を求める場合はPythonでも同様のコードになるので、そこまで気にならないと思います。

### listのi番目の要素を更新する

例: list `a` の2番目の要素を3に更新する。

```python:Python
a[2] = 3
```

```rust:Rust
a[2] = 3;
```

Rust では `a` は `mut` 修飾子付きで宣言されている必要があることに注意です。

### listの末尾に要素を追加する

例: list `c` に 42 を追加する。

```python:Python
c.append(42)
```

```rust:Rust
c.push(42);
```

### listの末尾要素を削除する

例: list `b` の末尾の要素を削除し、削除した要素を `tail` に束縛する。

```python:Python
tail = b.pop()
```

```rust:Rust
let tail = b.pop().unwrap();
```

Rust では `unwrap` する必要があることに注意です（他のデータ構造も同様）。

## dict

Rustでは[std::collections::HashMap](https://doc.rust-lang.org/std/collections/struct.HashMap.html)を使います。

ideoneでの実行結果

* [Python](http://ideone.com/4txhAj)
* [Rust](http://ideone.com/bPpxZt)

### dictを生成する

例1: 空のdict `scovilles` を生成する。

```python:Python
scovilles = {}
```

```rust:Rust
let mut scovilles = std::collections::HashMap::new();
```

あらかじめ、 `use std::collections::HashMap;` を宣言すると、 `let mut scovilles = HashMap::new();` と書くことができます。

例2: 'a'から'z'をキーとし、それらのアスキーコードを項目とするdict `asciicodes` を生成する。

```python:Python
asciicodes = {
    chr(ord('a') + i): ord('a') + i
    for i in range(26)
}
```

```rust:Rust
let asciicodes: std::collections::HashMap<_, _> = (0..26)
    .map(|i| {
        let ascii_code = ('a' as u8) + i;
        (ascii_code as char, ascii_code as i64)
    })
    .collect();
```

Rustではキーと項目のタプルをcollectさせることで、宣言的にdictを作成できます。

### dictに項目を設定する

例: dict `scovilles` に 'habanero' から 100,000 へのマッピングを設定（既に存在する場合は項目を上書き）する。

```python:Python
scovilles['habanero'] = 100_000
```

```rust:Rust
scovilles.insert("habanero", 100_000);
```

Rustでは `scovilles["habanero"] = 100_000;` とは書けないです。

### dictの要素数を求める

例: dict `scovilles` の項目数を `cardinality` に束縛する。

```python:Python
cardinality = len(scovilles)
```

```rust:Rust
let cardinality = scovilles.len();
```

### ある要素がdictのキーとして存在するか判定する

例: dict `scovilles` のキーに 'reaper' が含まれるならば真、そうでなければ偽を `has_reaper` に束縛する。

```python:Python
has_reaper = 'reaper' in scovilles
```

```rust:Rust
let has_reaper = scovilles.contains_key(&"reaper");
```

Rustでは引数は参照型であることに注意してください(strの場合は `&` 付けなくてもよいですが）。

### dictの指定したキーの項目を求める

例1: dict `scovilles` のキー 'habanero' の項目を `habanero` に束縛する。

```python:Python
habanero = scovilles['habanero']
```

```rust:Rust
let habanero = scovilles[&"habanero"];
```

例2: dict `scovilles` の 'reaper' の項目を `reaper` に束縛する。ただし、 `scovilles` のキーに 'reaper' が含まれないならば 0 を束縛する。

```python:Python
reaper = scovilles.get('reaper', 0)
```

```rust:Rust
let reaper = *scovilles.get("reaper").unwrap_or(&0);
```

キーが存在しない可能性がある場合、Rustでもgetメソッドを使います。getメソッドはOptionを返すので[unwrap_or](https://doc.rust-lang.org/std/option/enum.Option.html#method.unwrap_or)メソッドを用いるとよいです。

### dictをイテレートする

例: dict `scovilles` のキーと項目のペアを空白区切りで1行ずつ出力する。

```python:Python
for k, v in scovilles.items():
    print(k, v)
```

```rust:Rust
for (&k, &v) in &scovilles {
    println!("{} {}", k, v);
}
```

### dictから項目を削除する

例: dict `scovilles` からキー 'habanero' とそれに対応する項目を削除する。

```python:Python
scovilles.pop('habanero')
```

```rust:Rust
scovilles.remove(&"habanero");
```

## set

Rustでは[std::collections::HashSet](https://doc.rust-lang.org/std/collections/struct.HashSet.html)を使います。
setとHashSetの関係はdictとHashMapの関係とほぼ同じです。

ideoneでの実行結果

* [Python](https://ideone.com/ZcyLN4)
* [Rust](http://ideone.com/gq6tB7)

### setを生成する

例1: 空のset `s` を生成する。

```python:Python
s = set()
```

```rust:Rust
let mut s = std::collections::HashSet::new();
```

例2: 0以上10未満の偶数のset `evens` を生成する。

```python:Python
s = set()
```

```rust:Rust
let evens: std::collections::HashSet<_> = (0..10)
    .filter(|&i| i % 2 == 0)
    .collect();
```

### setに要素を追加する

例: set `s` に 8 を追加する。

```python:Python
s.add(8)
```

```rust:Rust
s.insert(8);
```

### setの要素数を求める

例: set `s` の要素数を `cardinality` に束縛する。

```python:Python
cardinality = len(s)
```

```rust:Rust
let cardinality = s.len();
```

### ある要素がsetに含まれるか判定する

例: set `s` に 1 が含まれるならば真、そうでなければ偽を `has_one` に束縛する。

```python:Python
has_one = 1 in s
```

```rust:Rust
let has_one = s.contains(&1)
```

### setをイテレートする

例: set `s` の要素を空白区切りで1行ずつ出力する。

```python:Python
for x in s:
    print(x)
```

```rust:Rust
for &x in &s {
    println!("{}", x);
}
```

### setから要素を削除する

例: set `s` から 8 を削除する。

```python:Python
s.remove(8)
```

```rust:Rust
s.remove(&8);
```

## ヒープ

ここでは、（Pythonの `heapq` に合わせて）Minヒープとして扱う方法を説明します。Rustでは[std::collections::BinaryHeap](https://doc.rust-lang.org/std/collections/struct.BinaryHeap.html)を使います。

ideoneでの実行結果

* [Python](https://ideone.com/bS8ZBv)
* [Rust](http://ideone.com/hVAayM)

### 空のヒープを生成する

例: 空のヒープ `q` を生成する。

```python:Python
import heapq
q = []
```

```rust:Rust
let mut q = std::collections::BinaryHeap::new();
```

### ヒープに要素を追加する

例: ヒープ `q` に3, 1, 4 をこの順で追加する。

```python:Python
heapq.heappush(q, 3)
heapq.heappush(q, 1)
heapq.heappush(q, 4)
```

```rust:Rust
q.push(-3);
q.push(-1);
q.push(-4);
```

BinaryHeapはMaxヒープなので、符号を反転しています。
タプルを要素する場合でも、辞書式順序で比較するので、適宜符号を反転すればよいです
（Rust 1.15.1(2019/09/07時点でのAtCoderのRustのバージョン)では、[std::cmp::Reverse](https://doc.rust-lang.org/std/cmp/struct.Reverse.html)
は使用できないので注意してください）。

### ヒープの最小要素を求める

例: ヒープ `q` の最小要素を `top` に束縛する。

```python:Python
top = q[0]
```

```rust:Rust
let top = -(*q.peek().unwrap());
```

Rustの方は符号を反転した要素を追加しているので、符号を反転して元に戻しています。

### ヒープが空か判定する

例: ヒープ `q` が空ならば真、そうでなければ偽を `is_empty` に束縛する。

```python:Python
has_element = q == []
```

```rust:Rust
let is_empty = q.is_empty();
```

### ヒープの最小要素を取り出す

例: ヒープ `q` の最小要素を削除し、削除した要素を `popped` に束縛する。

```python:Python
popped = heapq.heappop(q)
```

```rust:Rust
let popped = -q.pop().unwrap();
```

popメソッドが返す値は参照型ではないので、参照外しは不要であることに注意してください。

## defaultdict

Rustでは[std::collections::HashMap](https://doc.rust-lang.org/std/collections/struct.HashMap.html)をdefaultdictとして使います。
HashMapからstd::collections::hash_map::Entryを取得し、Entryの[or_insert](https://doc.rust-lang.org/std/collections/hash_map/enum.Entry.html#method.or_insert)メソッドを用いてデフォルト値を得られるようにします。

ideoneでの実行結果

* [Python](https://ideone.com/PmfTqS)
* [Rust](https://ideone.com/ir0pBp)

### defaultdictを生成する

例: デフォルト値が0であるdefaultdict `scovilles` を生成する。

```python:Python
import collections
scovilles = defaultdict(int)
```

```rust:Rust
let mut scovilles = std::collections::HashMap::new();
```

`scovilles` はただのHashMapなのでdefaultdictではないですが、項目を取得する際に工夫することでdefaultdictのように扱えます。

### defaultdictに項目を設定する

例: defaultdict `scovilles` に 'reaper' から 2,000,000 へのマッピングを設定（既に存在する場合は項目を上書き）する。

```python:Python
scovilles['reaper'] = 2_000_000
```

```rust:Rust
scovilles.insert("reaper", 2_000_000);
```

### defaultdictの指定したキーの項目を求める

例: defaultdict `scovilles` のキー 'habanero' の項目を `habanero` に束縛する。ただし、 `scovilles` にキー 'habanero' が存在しない場合、
`scovilles` に 'habanero' から 0(デフォルト値) へのマッピングを設定した上で `habanero` にはデフォルト値である0を束縛する。

```python:Python
habanero = scovilles['habanero']
```

```rust:Rust
let habanero = *scovilles.entry("habanero").or_insert(0);
```

## Counter

defaultdict同様、Rustでは[std::collections::HashMap](https://doc.rust-lang.org/std/collections/struct.HashMap.html)をCounterとして使います。残念ながらPythonのように楽はできないです。

ideoneでの実行結果

* [Python](https://ideone.com/6dHmjo)
* [Rust](https://ideone.com/dPyEF0)

### Counterを生成する

例: リスト [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] の各整数に関するCounter `c` を生成する。

```python:Python
import collections
c = collections.Counter([3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5])
```

```rust:Rust
let mut c = std::collections::HashMap::new();
for &i in &vec![3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] {
    *(c.entry(i).or_insert(0)) += 1;
}
```

ここでもEntryの `or_insert` が役立ちます。

### 指定したキーのカウントを求める

例: Counter `c` の5のカウントを `num_of_five` に束縛する。

```python:Python
num_of_five = c[5]
```

```rust:Rust
let num_of_five = *c.get(&5).unwrap_or(&0);
```

dictと同様です。

### 指定したキーのカウントを増やす

例: Counter `c` の3のカウントを57増やす

```python:Python
c[3] += 57
```

```rust:Rust
*(c.entry(&3).or_insert(0)) += 57;
```

`or_insert` を用いることで加算代入できます。

## deque

Rustでは[std::collections::VecDeque](https://doc.rust-lang.org/std/collections/struct.VecDeque.html)を使います。

ideoneでの実行結果

* [Python](https://ideone.com/KcfFK5)
* [Rust](https://ideone.com/zJOuwQ)


### 空のdequeを生成する

例: 空のdeque `d` を生成する。

```python:Python
import collections
d = collections.deque()
```

```rust:Rust
let mut d = std::collections::VecDeque::new();
```

### dequeの先頭に要素を追加する

例: deque `d ` の先頭に 4 を追加する。

```python:Python
d.appendleft(4)
```

```rust:Rust
d.push_front(4);
```

### dequeの末尾に要素を追加する

例: deque `d ` の末尾に 2 を追加する。

```python:Python
d.append(2)
```

```rust:Rust
d.push_back(2);
```

### dequeの要素数を求める

deque `d `の要素数を `cardinality` に束縛する

```python:Python
cardinality = len(d)
```

```rust:Rust
let cardinality = d.len();
```

### dequeの先頭要素を求める

例: deque `d` の先頭要素を `head` に束縛する。

```python:Python
head = d[0]
```

```rust:Rust
let head = *d.front().unwrap();
```

### dequeの末尾要素を求める

例: deque `d` の末尾要素を `tail` に束縛する。

```python:Python
tail = d[-1]
```

```rust:Rust
let tail = *d.back().unwrap();
```

### dequeの先頭要素を削除する

例: deque `d` の先頭要素を削除し、削除した要素を `popped_head` に束縛する。

```python:Python
popped_head = d.popleft()
```

```rust:Rust
let popped_head = d.pop_front().unwrap();
```

### dequeの末尾要素を削除する

例: deque `d` の末尾要素を削除し、削除した要素を `popped_tail` に束縛する。

```python:Python
popped_tail = d.pop()
```

```rust:Rust
let popped_tail = d.pop_back().unwrap();
```

# イテレート

Pythonのコードではitertoolsモジュールとfunctoolsモジュールがインポートされているとして説明します。

```python:Python
import itertools
import functools
```

ideoneでの実行結果

* [Python](https://ideone.com/D9mlbN)
* [Rust](http://ideone.com/JCRFWl)

## reversed

例: 整数リスト `xs` の順序を逆転したリストを `rev_xs` に束縛する。

```python:Python
rev_xs = list(reversed(xs))
```

```rust:Rust
let rev_xs: Vec<i64> = xs.iter().map(|&x| x).rev().collect();
```

`.map(|&x| x)` は `.copied()` の代用です（Rust 1.15.1(2019/09/07時点でのAtCoderのRustのバージョン)では、Iteratorにcopiedメソッドがないため）。

## accumulate

例: 整数リスト `xs` の累積和のリストを `acc` に束縛する。

```python:Python
acc = list(itertools.accumulate(xs))
```

```rust:Rust
let acc: Vec<_> = xs.iter()
    .scan(0, |state, &x| { *state += x; Some(*state) })
    .collect();
```

## zip

例: 整数リスト `xs` と `ys` から要素を集めたリストを `xys` に束縛する。

```python:Python
xys = list(zip(xs, ys))
```

```rust:Rust
let xys: Vec<_> = xs.iter().map(|&x| x).zip(ys.iter().map(|&x| x)).collect();
```

## map

例: 整数リスト `xs` の各要素を2乗したリストを `sqs` に束縛する。

```python:Python
sqs = list(map(lambda x: x**2, xs))
```

```rust:Rust
let sqs: Vec<_> = xs.iter().map(|&x| x.pow(2)).collect();
```

## filter

例: 整数リスト `xs` から奇数の要素を抽出したリストを `odds` に束縛する。

```python:Python
odds = list(filter(lambda x: x % 2 == 1, xs))
```

```rust:Rust
let odds: Vec<_> = xs.iter().filter(|&&x| x % 2 == 1).map(|&x| x).collect();
```

## reduce

例: フィボナッチ数列 [0, 1, 1, 2, 3, 5, 8, ...] の第5項（0-indexed）を `fib5` に束縛する。

```python:Python
fib5, _ = functools.reduce(
    lambda p, _: (p[0] + p[1], p[0]),
    range(4),
    (1, 0)
)
```

```rust:Rust
let (fib5, _) = (0..4).fold(
    (1, 0),
    |(p, pp), _| (p + pp, p)
);
```

Pythonではlambda関数の引数に対してアンパック代入を適用できませんが、Rustではそれが可能です。添字アクセスしなくて済むのは嬉しいですね。

## max/min

例1: 整数リスト `xs` の最大値を `x_max` に束縛する。

```python:Python
x_max = max(xs)
```

```rust:Rust
let x_max = *xs.iter().max().unwrap();
```

例2: 整数リスト `zs` の最小値を `z_min` に束縛する。ただし、 `zs` が空ならば0を `z_min` に束縛する。

```python:Python
z_min = min(zs, default=0)
```

```rust:Rust
let z_min = *zs.iter().max().unwrap_or(&0);
```

例3: 整数リスト `xs` に含まれる要素のうち、2で割った余りが最小となる要素を `x_argmin` に束縛する。ただし、そのような要素が複数存在する場合、リストの先頭に近い要素を `x_argmin` に束縛する。

```python:Python
x_argmin = min(xs, key=lambda x: x % 2)
```

```rust:Rust
let x_argmin = *xs.iter().min_by_key(|&&x| x % 2).unwrap();
```

## sum

例: 整数リスト `xs` の各要素の和を `s` に束縛する。

```python:Python
s = sum(xs)
```

```rust:Rust
let s: i64 = xs.iter().sum();
```

## all/any

例1: 整数リスト `xs` の要素がすべて奇数ならば真、そうでなければ偽を `is_all_odd` に束縛する。

```python:Python
is_all_odd = all(x % 2 == 1 for x in xs)
```

```rust:Rust
let is_all_odd = xs.iter().all(|&x| x % 2 == 1);
```

例2: 整数リスト `xs` の要素に偶数が存在するならば真、そうでなければ偽を `does_exist_even` に束縛する。

```python:Python
does_exist_even = any(x % 2 == 0 for x in xs)
```

```rust:Rust
let does_exist_even = xs.iter().any(|&x| x % 2 == 0);
```

## enumerate

例: 整数リスト `xs` から各要素のインデックス(0-indexed)とその要素をペアにしたリストを `indexed_xs` に束縛する。

```python:Python
indexed_xs = [(i, x) for i, x in enumerate(xs)]
```

```rust:Rust
let indexed_xs: Vec<_> = xs.iter().map(|&x| x).enumerate().collect();
```

Rustではインデックスの開始番号を指定できないことに注意してください。例えば、1-indexedにしたい場合は、1スタートのrangeオブジェクトとzipさせればよいです。

## sorted

例: 整数リスト `xs` を昇順ソートしたリストを `sorted_xs` に束縛する。

```python:Python
sorted_xs = sorted(xs)
```

```rust:Rust
let sorted_xs: Vec<_> = {
    let mut tmp_xs = xs.clone();
    tmp_xs.sort();
    tmp_xs
};
```

Rustの標準ライブラリには非破壊的なソートメソッドは存在しません。

## range

例1: 0以上10未満の整数のリストを `ps` に束縛する。

```python:Python
ps = list(range(10))
```

```rust:Rust
let ps: Vec<_> = (0..10).collect();
```

例2: 1以上10未満の整数のリストを `qs` に束縛する。

```python:Python
qs = list(range(1, 10))
```

```rust:Rust
let qs: Vec<_> = (1..10).collect();
```

なお、 Rust 1.15.1(2019/09/07時点でのAtCoderのRustのバージョン)では、rangeのstepをカスタムするのは（スマートには）できないです。

## スライス

例1: 整数リスト `xs` の先頭から3番目まで(0-indexed, exclusive)の要素から成るリストを `heads` に束縛する。

```python:Python
heads = xs[:3]
```

```rust:Rust
let heads = xs[..3].to_vec();
```

例2: 整数リスト `xs` の3番目から(0-indexed, inclusive)末尾までの要素から成るリストを `tails` に束縛する。

```python:Python
tails = xs[3:]
```

```rust:Rust
let tails = xs[3..].to_vec();
```

# 文字列

標準入出力でも述べた通り、Rustでは文字列を `Vec<char>` として扱うと使い勝手がよいです。
`Vec<char>` として扱えば、listで述べた操作が可能なので、i文字目の取得や特定の文字のカウントが可能です。

ここでは、数字の文字を整数に変換する方法と整数を文字列に変換する方法についてのみ述べます。

ideoneでの実行結果

* [Python](https://ideone.com/Tp2rV9)
* [Rust](https://ideone.com/xMfGts)

## int

例: 文字 '1' を整数1として `x` に束縛する。

```python:Python
x = int('1')
```

```rust:Rust
let x = '1'.to_digit(10).unwrap() as i64;
```

`'1' as i64` だと `x` は49（'1'のASCIIコード）になることに注意してください。

## str

例: 整数42を文字列として `s` に束縛する。

```python:Python
s = str(42)
```

```rust:Rust
let y: Vec<_> = 42.to_string().chars().collect();
```

Rustでは文字のリストとして `s` に束縛しています。
String型として束縛したいならば、単に `let y = 42.to_string();` でよいです。

# 数学

ideoneでの実行結果

* [Python](http://ideone.com/Pj7zaC)
* [Rust](http://ideone.com/ziapsL)

## abs

例: 整数 `x` の絶対値を `a` に束縛する。

```python:Python
a = abs(x)
```

```rust:Rust
let a = x.abs();
```

## gcd

例: 整数 `p`, `q` の最大公約数を `g` に束縛する。

```python:Python
import fractions
p = 12
q = 18
g = fractions.gcd(p, q)
```

AtCoderのPythonバージョンは3.4.3なので、math.gcdではなくfractions.gcdを用いています。

```rust:Rust
let g = {
    fn gcd(x: i64, y: i64) -> i64 {
        if y == 0 {
            x
        } else {
            gcd(y, x % y)
        }
    }
    gcd(p, q)
};
```

残念ながら、Rustの標準ライブラリにはgcdはありません。

## pow

例1: 正の整数 `q`, `n` について、 `q` の `n` 乗を `z` に束縛する。

```python:Python
z = q**n
```

```rust:Rust
let z = q.pow(n);
```

例2: 整数 `q` の $10^9 + 5$ 乗に対する $10^9 + 7$ の剰余を `r` に束縛する。

```python:Python
r = pow(q, 10**9 + 5, 10**9 + 7)
```

```rust:Rust
let r = {
    fn mod_pow(x: i64, y: i64, z: i64) -> i64 {
        if y == 0 {
            1
        } else {
            let h = mod_pow(x, y / 2, z);
            let res = (h * h) % z;
            if y % 2 == 0 {
                res
            } else {
                (res * x) % z
            }
        }
    }
    mod_pow(q, 1_000_000_005, 1_000_000_007)
};
```

Rustのpowは剰余をとるべき乗を求められないので、自力でダブリングしています。

## sqrt

例: 正の整数 `q` の平方根を `s` に束縛する。

```python:Python
import math
s = math.sqrt(q)
```

```rust:Rust
let s = (q as f64).sqrt();
```

i64にはsqrtメソッドはないので、f64にキャストします。

# bisect

RustのVecには[binary_search](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.binary_search)メソッドがありますが、同一の要素が複数存在する場合、得られるインデックスは不定なので、競技プログラミングにおいて使うのは厳しいです。
仕方ないので、自力で二分探索します。

ideoneでの実行結果

* [Python](https://ideone.com/Ot4BYU)
* [Rust](https://ideone.com/qEIrw7)

## bisect_left

例: 昇順ソートされている整数のリスト `x` から、5以上の要素のうち、最小のインデックスを `i` に束縛する。

```python:Python
i = bisect.bisect_left(x, 5)
```

```rust:Rust
fn bis<P>(ok: i64, ng: i64, p: P) -> i64
    where P: Fn(i64) -> bool {
    let mid = (ok + ng) / 2;
    if (ok - ng).abs() == 1 {
        ok
    } else if p(mid) {
        bis(mid, ng, p)
    } else {
        bis(ok, mid, p)
    }
}
let i = bis(x.len() as i64, -1, |i| x[i as usize] >= 5);
println!("i = {}", i);
```

Rustの `bis` は二分探索を行う関数です（所謂めぐる式）。
i64に対して二分探索を行うので、Vecの要素にアクセスする際はusizeにキャストしています。

## bisect

例: 昇順ソートされている整数のリスト `x` から、5より大きい要素のうち、最小のインデックスを `j` に束縛する。

```python:Python
j = bisect.bisect(x, 5)
```

```rust:Rust
fn bis<P>(ok: i64, ng: i64, p: P) -> i64
    where P: Fn(i64) -> bool {
    let mid = (ok + ng) / 2;
    if (ok - ng).abs() == 1 {
        ok
    } else if p(mid) {
        bis(mid, ng, p)
    } else {
        bis(ok, mid, p)
    }
}
let j = bis(x.len() as i64, -1, |i| x[i as usize] > 5);
println!("j = {}", j);
```

Rustのコードは `bis` のクロージャの不等号から等号が外れています。

# おわりに

比較してみると、やはりPythonの方がコーディングは楽ですが、Rustもそれほど悪くないかなと感じます
（標準ライブラリがやや貧弱なのがつらいですが）。
個人的には、Rustのクロージャのパターンマッチがお気に入りです。