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();