Skip to content

Instantly share code, notes, and snippets.

@niku
Forked from sandinist/fibcalc.exs
Last active August 29, 2015 13:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niku/9971916 to your computer and use it in GitHub Desktop.
Save niku/9971916 to your computer and use it in GitHub Desktop.
defmodule Fibcalc do
def calc_fibs(list) do
# 今回「プロセスを生成して,生成したプロセスの中で計算して,その結果を送ってもらう」という処理をこれから書く.
# 送ってもらう先は自分になるので,自分のpidを覚えておく.
me = self
# ```[1,2,3] |> Enum.map(fn (elem) -> elem + 1 end)```
# は
# ```Enum.map([1,2,3], fn (elem) -> elem + 1 end)```
# と同じ.|>の左側の結果が,|>の右側の式の第一引数になる.
# 「各リストに1を足して,それから2を掛ける」
# ```[1,2,3] |> Enum.map(fn (elem) -> elem + 1 end) |> Enum.map(fn (elem) -> elem * 2 end)```
# といったような処理の流れを書くのに便利
list
|>
Enum.map(fn (elem) ->
# spawn(body)でプロセスを生成して,bodyの中のことをやってもらう
spawn fn ->
# send(pid, body)でpidへbodyを送る
# ここではpidにmeを指定しているので,
# 自分へ {spawnした先のpid, 元の値,計算結果} のタプルを送る
send(me, {self, elem, fib(elem)})
end
end)
# listの数だけ結果が送られてくるはずなので待つ
waitn(Enum.count(list))
end
# ```fib(0)```で関数fibに渡ってくる変数が0の場合,という処理を書ける
def fib(0), do: 1
def fib(1), do: 1
def fib(n), do: fib(n-1) + fib(n-2)
defp waitn(0), do: IO.puts "done!"
defp waitn(n) do
IO.puts "remain #{n} times..."
# sendされてきたやつはreceiveで受け取れる
# sendされてきたやつのことをメッセージという.
# 今回は自分に対してメッセージを送ったので,自分で受け取る.
# メッセージが何個たまっていても,receive1回につき1つのメッセージしか受け取らない(受け取れない)
receive do
{pid, number, result} -> IO.inspect {pid, number, result}
end
# 複数回メッセージを受け取りたい場合,Elixirでは再帰するのが一般的
waitn(n-1)
end
end
Fibcalc.calc_fibs([12, 3, 11, 4, 24, 31, 28, 10])
#> remain 8 times...
#> {#PID<0.41.0>, 12, 233}
#> remain 7 times...
#> {#PID<0.42.0>, 3, 3}
#> remain 6 times...
#> {#PID<0.43.0>, 11, 144}
#> remain 5 times...
#> {#PID<0.44.0>, 4, 5}
#> remain 4 times...
#> {#PID<0.48.0>, 10, 89}
#> remain 3 times...
#> {#PID<0.45.0>, 24, 75025}
#> remain 2 times...
#> {#PID<0.47.0>, 28, 514229}
#> remain 1 times...
#> {#PID<0.46.0>, 31, 2178309}
#> done!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment