Собственно вариант на Эрланге:
-module(cham).
-export([start/1, creature/2, meeting_place/1, meeting_place/2]).
creature(Colour, MPPid) ->
MPPid ! {self(), Colour},
creature(Colour, MPPid, 0).
creature(Colour, MPPid, Met) ->
receive
faded ->
MPPid ! Met;
OColour when is_atom(OColour) ->
NColour = complement({Colour, OColour}),
MPPid ! {self(), NColour},
creature(NColour, MPPid, Met+1)
end.
meeting_place(N) ->
meeting_place(N, 0).
meeting_place(0, _) ->
end_meeting(0, 4);
meeting_place(N, Cr) ->
receive
{CrPid, Colour} when is_tuple(Cr) ->
{CrPid1, Colour1} = Cr,
CrPid ! Colour1,
CrPid1 ! Colour,
meeting_place(N-1, 0);
{CrPid, Colour} ->
meeting_place(N, {CrPid, Colour})
end.
end_meeting(TMet, 0) ->
io:format("Total meetings: ~p~n", [TMet]);
end_meeting(TMet, Crs) ->
receive
{CrPid, _} ->
CrPid ! faded,
end_meeting(TMet, Crs);
Met when is_number(Met) ->
end_meeting(TMet + Met, Crs-1)
end.
start(N) ->
MPPid = spawn(?MODULE, meeting_place, [N]),
spawn(?MODULE, creature, [blue, MPPid]),
spawn(?MODULE, creature, [red, MPPid]),
spawn(?MODULE, creature, [yellow, MPPid]),
spawn(?MODULE, creature, [blue, MPPid]).
complement(Pair) ->
case Pair of
{blue, red} -> yellow;
{blue, yellow} -> red;
{blue, blue} -> blue;
{red, yellow} -> blue;
{red, blue} -> yellow;
{red, red} -> red;
{yellow, yellow} -> yellow;
{yellow, red} -> blue;
{yellow, blue} -> red;
{faded, _} -> faded;
_Else -> erlang:error(badarg)
end.
Производительность еще не успел замерить до конца, хочу еще в виде кластера creature'ов попробовать запустить по сетке.