競プロで使えそうなRustのitertoolsのマクロとメソッドまとめ

Rustのitertoolsなんとなく使っていたのですが、
時間とってどんなメソッドやマクロがあるのかなと眺めてみたので恣意的にピックアップしてまとめました。

# 順列、組み合わせ系

## permutations

順列を返却してくれます。

```rust
let perms = (5..8).permutations(2);
itertools::assert_equal(perms, vec![
    vec![5, 6],
    vec![5, 7],
    vec![6, 5],
    vec![6, 7],
    vec![7, 5],
    vec![7, 6],
]);
```

## combinations

名前の通り、組み合わせを返却してくれます。

```rust
let it = (1..5).combinations(3);
itertools::assert_equal(it, vec![
    vec![1, 2, 3],
    vec![1, 2, 4],
    vec![1, 3, 4],
    vec![2, 3, 4],
]);
```

## tuple_combinations

組み合わせをtupleで返却してくれます。

```rust
let mut v = Vec::new();
for (a, b) in (1..5).tuple_combinations() {
    v.push((a, b));
}
assert_eq!(v, vec![(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]);
```


## combinations_with_replacement

この記事をまとめるきっかけになったメソッドです。(重複組合せっていうらしい)
自前実装してたのですが、他の方の回答でこちら使っていて感動しました。

```rust
let it = (1..4).combinations_with_replacement(2);
itertools::assert_equal(it, vec![
    vec![1, 1],
    vec![1, 2],
    vec![1, 3],
    vec![2, 2],
    vec![2, 3],
    vec![3, 3],
]);
```

# ループ系

## iproduct!

2重ループや3重ループをすっきりかける。

```rust
// Iterate over the coordinates of a 4 x 4 x 4 grid
// from (0, 0, 0), (0, 0, 1), .., (0, 1, 0), (0, 1, 1), .. etc until (3, 3, 3)
for (i, j, k) in iproduct!(0..4, 0..4, 0..4) {
   // ..
}
```

## izip!

まとめてイテレーションしたいときに使えそう。

```rust
// iterate over three sequences side-by-side
let mut results = [0, 0, 0, 0];
let inputs = [3, 7, 9, 6];

for (r, index, input) in izip!(&mut results, 0..10, &inputs) {
    *r = index * 10 + input;
}

assert_eq!(results, [0 + 3, 10 + 7, 29, 36]);
```

## tuple_windows

基本的には`windows()`で事足りそうな気もするけど。。
重複なしの場合は`tuples<T>(self)`というメソッドも用意されている。

```rust
let mut v = Vec::new();
for (a, b) in (1..5).tuple_windows() {
    v.push((a, b));
}
assert_eq!(v, vec![(1, 2), (2, 3), (3, 4)]);
```

## cartesian_product

直積。あんまり使う機会はなさそうですが・・・

```rust
let it = (0..2).cartesian_product("αβ".chars());
itertools::assert_equal(it, vec![(0, 'α'), (0, 'β'), (1, 'α'), (1, 'β')]);
```

# インデックス検索系

## positions

条件に一致するインデックスを`Vec<>`で返却してくれます。
`enumerate`を使用しなくてもインデックスがわかるのは便利そうな気もします。

```rust
let data = vec![1, 2, 3, 3, 4, 6, 7, 9];

itertools::assert_equal(data.iter().positions(|v| v % 2 == 0), vec![1, 4, 5]);
itertools::assert_equal(data.iter().positions(|v| v % 2 == 1).rev(), vec![7, 6, 3, 2, 0]);
```

## find_position

最小の要素を見つけ出す`position_min`、
最大の要素を見つけ出す`position_max`もあったので使えるかも。
どっちも欲しい場合は`position_minmax`もありました。

カスタムで順序制御したい場合のために`position_min_by`もあったので覚えておくといつか使えるかも。

```rust
let text = "Hα";
assert_eq!(text.chars().find_position(|ch| ch.is_lowercase()), Some((1, 'α')));
```

# その他

## merge

順序を制御したい場合は`fn merge_by<J, F>(self, other: J, is_first: F)`
もともとマージソートを自前で実装していたので、`merge_by`は便利かも。

```rust
let a = (0..11).step(3);
let b = (0..11).step(5);
let it = a.merge(b);
itertools::assert_equal(it, vec![0, 0, 3, 5, 6, 9, 10]);
```

## unique

重複を飛ばしてくれる(ソートされていなくてもOK)
こちらも`fn unique_by<V, F>(self, f: F)`が用意されているので、カスタムして重複を削除できる。

```rust
let data = vec![10, 20, 30, 20, 40, 10, 50];
itertools::assert_equal(data.into_iter().unique(), vec![10, 20, 30, 40, 50]);
```

## all_equal

すべてが同じかどうかを判定してくれます。そんなに需要はない気もしますが。。

```rust
let data = vec![1, 1, 1, 2, 2, 3, 3, 3, 4, 5, 5];
assert!(!data.iter().all_equal());
assert!(data[0..3].iter().all_equal());
assert!(data[3..5].iter().all_equal());
assert!(data[5..8].iter().all_equal());
```

## tree_fold1

ぱっと使用法は思いつきませんでしたが面白かったので転記します笑

```rust
// The same tree as above
let num_strings = (1..8).map(|x| x.to_string());
assert_eq!(num_strings.tree_fold1(|x, y| format!("f({}, {})", x, y)),
    Some(String::from("f(f(f(1, 2), f(3, 4)), f(f(5, 6), 7))")));

// Like fold1, an empty iterator produces None
assert_eq!((0..0).tree_fold1(|x, y| x * y), None);

// tree_fold1 matches fold1 for associative operations...
assert_eq!((0..10).tree_fold1(|x, y| x + y),
    (0..10).fold1(|x, y| x + y));
// ...but not for non-associative ones
assert_ne!((0..10).tree_fold1(|x, y| x - y),
    (0..10).fold1(|x, y| x - y));
```