概要
しばらく前に来ていたズンドコブームに乗り損ねましたが、自分なりにElixirで書いてみました。
実装
- 状態の保持はAgent
-
ズン
かドコ
を1つ足しては全体から5個切り出すを繰り返す - 1つ足すついでに標準出力へ出力(副作用なのでちょっと微妙)
- 5個切り出したのが目的の
ズンズンズンズンドコ
と一致したら、終了 -
iex
で実行すると文字化けが起きるので、最後に実行用の1行を追加した。
zundoko.exs
defmodule Zundoko do
def run do
{:ok, agent} = Zundoko.start
Zundoko.run(agent)
end
def run(pid) when is_pid(pid) do
if Zundoko.complete?(pid) do
IO.puts "キ・ヨ・シ!"
else
Zundoko.add(pid)
Zundoko.run(pid)
end
end
def start do
Agent.start_link(fn -> [] end)
end
def get(pid) do
Agent.get(pid, fn prev ->
prev |> Enum.reverse |> Enum.join
end)
end
def add(pid) do
next = Zundoko.random
IO.write(next)
Agent.update(pid, fn prev ->
[next | prev] |> Enum.take(5)
end)
end
def complete?(pid) do
Zundoko.get(pid) == "ズンズンズンズンドコ"
end
def random do
["ズン", "ドコ"]
|> Enum.random
end
end
Zundoko.run
やってみて
やっぱり、考えなしにやるとまだ副作用の残る設計になってしまう(要改善)。
今回のだと、5個切り出したのを状態として保持するのではなく、それまで出たのすべてを保持して最後に返せば副作用を排除できそう。その場合、あんまり長いと出力の際に問題になりそう。5個に切り分ける部分を分離させて、5個ずつ表示させていけば解決するかな?