愛を生む二人を探してという記事が面白かったので、 Rust でも試してみました。
couple.rs
use std::char;
/// 定数『愛』
const KANJI_AI: char = '愛';
/// 『愛』を生む可能性のある、『愛』以外の文字の配列を返す。
fn create_kanji_list() -> Vec<char> {
let mut vec = Vec::new();
// /[一-龠]/ の範囲を検索
for bits in ('一' as u32)..('龠' as u32) {
if bits != KANJI_AI as u32 && bits & KANJI_AI as u32 == KANJI_AI as u32 {
vec.push(char::from_u32(bits).expect(format!("{:#x} 有効な文字ではありません。", bits).as_str()));
}
}
vec
}
/// 文字の配列を元に、『愛』を生むペアを返す。
fn search(list: Vec<char>) -> Vec<(char, char)> {
let mut pairs = Vec::new();
for (i, kanji_1) in list.iter().enumerate() {
for kanji_2 in list.iter().skip(i + 1) {
if *kanji_1 as u32 & *kanji_2 as u32 == KANJI_AI as u32 {
pairs.push((*kanji_1, *kanji_2));
}
}
}
pairs
}
fn main() {
let kanji_pairs = search(create_kanji_list());
for kanji_pair in kanji_pairs.iter() {
println!("{},{}", kanji_pair.0, kanji_pair.1);
}
}
結果
出力結果は GitHub-Gist の pairs_list.txt をご覧ください。
2722行目に本家大元『死』と『生』のペアが、2313行目に椛(もみじ)ちゃんと猛(たける)くんのペアがいます。
出力が同じであるか確認するためのプログラムは以下の通り。
check.rs
use std::path::Path;
use std::fs::File;
use std::io::BufRead;
use std::io::BufReader;
/// &str 型から char 型に変換
/// # Panics
/// 文字列が1文字ではなかった場合、 panic を発生させる。
fn get_char(s: &str) -> char {
if s.chars().count() == 1 {
String::from(s).pop().unwrap()
} else {
panic!();
}
}
/// `path` で指定されたファイルから、『愛』を生むペアのリストを読み込み、配列として返す。
fn read_pair_list(path: &str) -> Vec<(char, char)> {
let mut vec = Vec::new();
let file = File::open(Path::new(path)).unwrap();
for line in BufReader::new(&file).lines() {
let line = line.unwrap();
let v: Vec<&str> = line.split(',').collect();
vec.push((get_char(v[0]), get_char(v[1])));
}
vec
}
fn main() {
// オリジナルの出力結果
let list_1 = read_pair_list("couples.txt");
// 『 Rust でも愛を生む二人を探す』の出力結果
let mut list_2 = read_pair_list("pairs_list.txt");
// 出力結果の比較
for pair_1 in list_1.iter() {
for idx in 0..list_2.len() {
if list_2[idx] == (pair_1.0, pair_1.1)
|| list_2[idx] == (pair_1.1, pair_1.0) {
list_2.swap_remove(idx);
break;
}
}
}
if list_2.len() == 0 {
//-- すべてのペアが一致
println!("一致");
} else {
//-- 一致しないペアが存在
println!("不一致");
}
}
無事、一致しました!
なんでアルゴリズムが違うの?
私が理解できなかったからです(泣)。