LoginSignup
4
4

More than 5 years have passed since last update.

Rust でも愛を生む二人を探す

Last updated at Posted at 2016-05-20

愛を生む二人を探してという記事が面白かったので、 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!("不一致");
    }
}

無事、一致しました!

なんでアルゴリズムが違うの?

私が理解できなかったからです(泣)。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4