require Tuple
require List
defmodule Rand do
def rand do
elem Time.utc_now().microsecond,0
end
end
defmodule Example do
def special(t, s) do
if s == 5 do
-1
else
if elem(t, s) && elem(t, rem(s+1, 5)) do
s
else
special(t, s+1)
end
end
end
def judge(t) do
special(t, 0)
end
def run(flag, caller, name) do
if flag == false do # flag = false is thinking
send caller, {:want_eat, self()}
[eat, index] = receive do
{:yes, index2} -> [true, index2]
{:no,} -> [false, -1]
end
if eat do
IO.puts "PhD#{name} will eat"
send caller, {:want_think, index, self()}
run true, caller, name
else
IO.puts "PhD#{name} won't eat"
run false, caller, name
end
else #finish eating
IO.puts "PhD#{name} will think"
run false, caller, name
end
end
def listen(t, pos) do
if pos > 0 do
s = judge(t)
[k, index, p] = receive do
{:want_eat, pid} ->
if s > -1 do
[put_elem(put_elem(t, s, !elem(t, s)), rem(s+1, 5), !elem(t, rem(s+1, 5))), s, pid]
else
[t, -1, pid]
end
{:want_think, x, pid} ->
[put_elem(put_elem(t, x, !elem(t, x)), rem(x+1, 5), !elem(t, rem(x+1, 5))), -2, pid]
end
if index >= 0 do
send p, {:yes, index}
else
if index >= -1 do
send p, {:no}
end
end
listen(k, pos-1)
end
end
end
defmodule Creat do
def creat(x, caller) do
if x > 0 do
spawn Example, :run, [false, caller, x]
creat(x-1, caller)
end
end
end
pid = spawn Example, :listen, [Tuple.duplicate(true, 5), 100]
Creat.creat(5, pid)
IO.puts ""
最近两天在看Eilxir,就用它写了一下哲学家就餐问题,运行结果不稳定,尚需要研究
PhD5 will eat
PhD4 will eat
PhD3 won't eat
PhD2 won't eat
PhD1 won't eat
PhD5 will think
PhD4 will think
PhD2 will eat
PhD3 will eat
PhD1 won't eat
PhD3 will think
PhD5 won't eat
PhD2 will think
PhD4 won't eat
PhD1 will eat
PhD5 won't eat
PhD3 will eat
PhD2 won't eat
PhD1 will think
PhD4 won't eat
PhD5 will eat