第1章の08から09まで(言語処理100本ノック2020)

Posted by johtani on Friday, May 8, 2020

目次

Rustで言語処理100本ノックのリファクタリングの続き。

前回はこちら

とっくに終わってたのに、ブログ書いてなかった。。。

08. 暗号文

pub fn cipher(text: &str) -> String {
    return String::from_iter(text.chars().map(|x| {
        if x.is_ascii_alphanumeric() && x.is_lowercase() {
            let mut b = [0; 4];
            x.encode_utf8(&mut b);
            b[0] = 219 - b[0];
            char::from(b[0])
        } else {
            x
        }
    }));
}

Rustの文字列はUTF-8でエンコードされたテキストを保持しているので、文字コード自体は意識していないです。 chars()でUnicodeスカラー値のイテレータが返ってくるので、1文字ずつ扱えるようになります。

ただ、1文字をバイトとして扱うのに手こずりました。 encode_utf8というメソッドを利用して1バイトだけ取り出して、計算するというのをやっています。 文字種の判別のメソッドが用意されているのは便利ですね。

なんかもうちょっとスマートにできないのかな?と思いつつ動いたのでこれになってます。

09. Typoglycemia

pub fn typoglycemia(text: &str) -> String {
    return text
        .split_whitespace()
        .map(|word| {
            if word.len() <= 4 {
                word.to_string()
            } else {
                let original = word.chars().collect::<Vec<char>>();
                let first = original.get(0).unwrap();
                let last = original.last().unwrap();
                let mut typo = original[1..original.len() - 1]
                    .iter()
                    .map(|x| x.clone())
                    .collect::<Vec<char>>();
                let mut rng = thread_rng();
                typo.shuffle(&mut rng);
                let mut typo = String::from_iter(typo.iter());
                typo.insert(0, first.clone());
                typo.push(last.clone());
                typo
            }
        })
        .collect::<Vec<String>>()
        .join(" ");
}

一応、1行で記述できたかな? まずは、スペースで単語ごとに区切った後に、word(単語)の長さによって、処理を分岐し、単語が5文字以上の場合にランダムに並び替えを行うというのをやっています。 文字単位で処理を行うために、chars()で1文字ずつ取り出しています。 最初と最後の文字だけはそのままに、間の文字をランダムにシャッフルするというのをやるのに、もとのwordのスライスからコピーした文字列を作り出してから組み立て直すということをやっています。

コピーしないでゴニョゴニョする方法ってあるのかなぁ? 思いつかなかったので、結構泥臭い感じの実装になってしまいました。

まとめ

めんどくさいので、コードをGitHubのソースコードからではなく、ブログにコードスニペットとしてコピペしました。Hugoでいい感じにGitHubのコードスニペット表示するのないかなぁ?

ということで、2年越しで1章が終了しました。 2章もやらないとなぁ。


comments powered by Disqus