Re: Простые и неправильные хамелеоны
От: Flamage Россия  
Дата: 21.05.07 22:30
Оценка: 23 (1)
Собственно вариант на Эрланге:

-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'ов попробовать запустить по сетке.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.