LoginSignup
2
0

Elixirで言語処理100本ノックやってみた!vol.8

Posted at

こんにちは!
3ヶ月で、Elixir言語で開発できるようになるため、奮闘中のこーへーです!

期間が空きましたが、8つ目の問題をどうにかこうにかクリアできたので、アップしていきたいと思います。

100本ノックの記事はこちら

08. 暗号文Permalink

与えられた文字列の各文字を,以下の仕様で変換する関数cipherを実装せよ

  • 英小文字ならば(219 - 文字コード)の文字に置換
  • その他の文字はそのまま出力
    この関数を用い,英語のメッセージを暗号化・復号化せよ

Cipherモジュールとconversion関数の作成

defmodule Cipher do
  def conversion(input_text) do
    input_text
    |> String.graphemes()
    |> Enum.map(fn x -> conversion_char(x) end)
    |> Enum.join()
  end

上記関数で、String.grahemes()を使っていますが、ここはcodepointsでも実現したいことは変わりません。ただ、grahemesは、Unicodeを解釈してくれる機能があります。
例えば、\u0065\u0301を変換すると次のようになります。

iex(30)> String.graphemes("\u0065\u0301")
["é"]

基本的には、各要素に分割した文字列リストを返してくれます。

conversion_char関数の作成

def conversion_char(x) do
    <<c :: utf8>> = x
    if c >= ?a and c <= ?z do
      <<219 - c :: utf8>>
    else
      x
    end
  end

これは、なかなかギョッとしますよね。
まず、<<c :: utf8>> = xの部分ですが、xに入ってきた文字を1文字づつ取り出して、cにバインドしています。
もし、utf8でなければエラーが発生します。

その次のif文は英子文字であるかをチェックしています。
正直ここは書き方がわからなかったので、少しチョンボしましたがこういう書き方があるんだと勉強になりました。

というわけで、全体を繋げると以下のようになります。

defmodule Cipher do
  def conversion(input_text) do
    input_text
    |> String.graphemes()
    |> Enum.map(fn x -> conversion_char(x) end)
    |> Enum.join()
  end

  @spec conversion_char(binary()) :: binary()
  def conversion_char(x) do
    <<c :: utf8>> = x
    if c >= ?a and c <= ?z do
      <<219 - c :: utf8>>
    else
      x
    end
  end
end

実行すると以下のようになります。

iex(32)> Cipher.conversion("すずき")
"すずき"
iex(33)> Cipher.conversion("abc")   
"zyx"
iex(34)> Cipher.conversion("0123")
"0123"
iex(35)> Cipher.conversion("ABC") 
"ABC"
iex(36)> Cipher.conversion("/////")
"/////"
iex(37)> Cipher.conversion(".......") 
"......."

2つ目に実行した"abc"という文字列は暗号化されて、それ以外はそのまま(復号化)されていることがわかるかと思います。

まとめ

今回の問題では、conversion関数の中で、conversion_char関数の呼び出しを行っています。
今までは、関数ひとつひとつを作ってそれぞれ実行していましたが、初の試みだったのでより柔軟な発想が必要だと感じました。

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