
if 文が長くなってしまいました。もっとスマートに書く方法はないでしょうか...。
use itertools::Itertools;
use proconio::input;
fn main() {
input! {n: usize}
let mut parentheses: Vec<String> = Vec::new();
for bit in 0..(1 << n) {
let s = (0..n)
.map(|digit| if (bit & (1 << digit)) == 0 { '(' } else { ')' })
.join("");
if s.chars().filter(|c| *c == '(').count() == s.chars().filter(|c| *c == ')').count()
&& s.chars()
.scan(0, |state, c| {
*state += if c == '(' { 1 } else { -1 };
Some(*state)
})
.all(|x| x >= 0)
{
parentheses.push(s);
}
}
parentheses.sort();
for s in parentheses {
println!("{}", s);
}
}
let n = 3;
for bit in 0..(1 << n) {
let s = (0..n)
.map(|digit| if (bit & (1 << digit)) == 0 { '(' } else { ')' })
.collect::<String>();
println!("{}", s);
}for 式の戻り値の () なので気にしないでください。ビットシフト と ビット論理積 を利用しています。if 文にて、カッコ列が正しいカッコ列かどうかを判別しています。正しいカッコ列の条件は'(')と終わり(')')が同じ数'(' の数」<「')' の数」となるケースが1回もないitertools.product('()', repeat=n) のようにすれば辞書順に列挙してくれるのですが、rust ではそのようなスマートな書き方はないのか気になります。itertools.product('()', repeat=n) の rust バージョンを考えてみました。multi_cartesian_product() を利用すると良さそうです。
// itertools が import 出来ないのでここでは動作しません!
use itertools::Itertools;
let n = 3;
let s: Vec<String> = (0..n)
.map(|_| "()".chars())
.multi_cartesian_product()
.map(|cs| cs.iter().collect())
.collect_vec();