0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Rustのマクロでモールス信号を実装してみた

Last updated at Posted at 2024-08-14

はじめに

最近SNSでギリギリダンスの動画がよく回ってきます。
参考動画:https://www.youtube.com/watch?v=jzi6RNVEOtA

その動画の中で”... --- ...”というモールス信号が使われています。
このモールス信号がプログラムの中でも使えたら面白いのではないかと思い、
今回モールス信号を入力するとアルファベットに変換されるマクロを実装しました。
Rustのマクロの前提知識については下記素晴らしい記事で補填いただくとして、
割愛させていただきます。
参考記事:https://qiita.com/k5n/items/758111b12740600cc58f

コード解説

1.実行結果

まずは実装したマクロ「morse!」の使い方について説明します。

  • 引数 :可変数、文字列でモールス信号を与える
  • 戻り値:なし
  • 処理 :引数に対応するアルファベットを表示する、対応がなければ"#"を表示する
main.rs
fn main() {
    //実行例1
    print!("morse signal to alphabet : ");
    morse!("....", ".-", ".--.", ".--.", "-.--");
    println!();

    //実行例2
    print!("morse signal to alphabet : ");
    morse!(".-.", "..-", "...", "-");
    println!();

    //実行例3
    print!("ギリギリダンス : ");
    morse!("...", "---", "...");
    println!();

    //実行例4
    print!("NG : ");
    morse!("2", "A", ".....");

}
morse signal to alphabet : HAPPY
morse signal to alphabet : RUST
ギリギリダンス : SOS
NG : ###

2.実装したマクロ

実装したマクロの全体像になります。

use std::collections::HashMap;
#[macro_export]
macro_rules! morse {
    ( $ ($term:tt),* ) => {
        {
            //モールス信号の対応テーブルを作成する
            let mut morse_table = HashMap::new();
            morse_table.insert(".-",   "A"); morse_table.insert("-...", "B"); morse_table.insert("-.-.", "C");
            morse_table.insert("-..",  "D"); morse_table.insert(".",    "E"); morse_table.insert("..-.", "F");
            morse_table.insert("--.",  "G"); morse_table.insert("....", "H"); morse_table.insert("..",   "I");
            morse_table.insert(".---", "J"); morse_table.insert("-.-",  "K"); morse_table.insert(".-..", "L");
            morse_table.insert("--",   "M"); morse_table.insert("-.",   "N"); morse_table.insert("---",  "O");
            morse_table.insert(".--.", "P"); morse_table.insert("--.-", "Q"); morse_table.insert(".-.",  "R");
            morse_table.insert("...",  "S"); morse_table.insert("-",    "T"); morse_table.insert("..-",  "U");
            morse_table.insert("...-", "V"); morse_table.insert(".--",  "W"); morse_table.insert("-..-", "X");
            morse_table.insert("-.--", "Y"); morse_table.insert("--..", "Z");

            //信号 → アルファベットに変換する
            $(
                match morse_table.get($term) {
                    Some(morse_alphabet) => print!("{}", morse_alphabet),
                    None => print!("#"),
                }
            ) *
        }
    };
}

2.1モールス信号の対応テーブルの実装

HashMap(連想配列)を使用して愚直にモールス信号とアルファベットの対応をコーディングしました。
※ほかに良い方法があればご教授ください。

モールス信号対応テーブル
//モールス信号の対応テーブルを作成する
            let mut morse_table = HashMap::new();
            morse_table.insert(".-",   "A"); morse_table.insert("-...", "B"); morse_table.insert("-.-.", "C");
            morse_table.insert("-..",  "D"); morse_table.insert(".",    "E"); morse_table.insert("..-.", "F");
            morse_table.insert("--.",  "G"); morse_table.insert("....", "H"); morse_table.insert("..",   "I");
            morse_table.insert(".---", "J"); morse_table.insert("-.-",  "K"); morse_table.insert(".-..", "L");
            morse_table.insert("--",   "M"); morse_table.insert("-.",   "N"); morse_table.insert("---",  "O");
            morse_table.insert(".--.", "P"); morse_table.insert("--.-", "Q"); morse_table.insert(".-.",  "R");
            morse_table.insert("...",  "S"); morse_table.insert("-",    "T"); morse_table.insert("..-",  "U");
            morse_table.insert("...-", "V"); morse_table.insert(".--",  "W"); morse_table.insert("-..-", "X");
            morse_table.insert("-.--", "Y"); morse_table.insert("--..", "Z");

2.2信号をアルファベットに変換する

HashMapで定義したモールス信号対応テーブルから引数「term」に対応するアルファベット取得を試みます。対応がある/なしに応じてmatch文で処理しています。
可変数引数をとるため、ここの処理は「$()*」で囲い、与えられた引数の分だけ繰り返します。

信号をアルファベットに変換
            //信号 → アルファベットに変換する
            $(
                match morse_table.get($term) {
                    Some(morse_alphabet) => print!("{}", morse_alphabet),
                    None => print!("#"),
                }
            ) *

終わりに

これで簡単にモールス信号をプログラム内で使うことができるようになりました。
Rustのマクロは可変数引数を簡単に実装できるのが大変便利ですね。
しかもマクロを書くのは楽しい、、

これからもテーマを見つけて楽しいマクロを実装していければと思います。

以上です!

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?