-module(chameneos). -export([run/0, run/1]). run() -> run(100). run(N) -> mall(N, [blue,red,yellow]), io:fwrite("~n~n"), mall(N, [blue,red,yellow,red,yellow,blue,red,yellow,red,blue]), io:fwrite("~n~n"). mall(N, Colours) -> % Create the chameneos Mall = self(), Pids = mapi(Colours, fun (Index, Colour) -> spawn(fun () -> chameneo(Index, Colour, Mall, 0) end) end), % N meeting interactions for(1, N, fun (_) -> receive {join,A_pid,A_name,A_colour} -> receive {join,B_pid,B_name,B_colour} -> A_pid ! {meet,B_name,B_colour}, B_pid ! {meet,A_name,A_colour}, ok end end end), % Tell the chameneos to stop. for_each(Pids, fun (_) -> receive {join,C_pid,_,_} -> C_pid ! {quit} end end), % Retrieve their results and print them. for_each(Pids, fun (_) -> receive {done,D_name,D_colour,D_meets} -> io:fwrite("~w\t~w\t~w\tzero~n", [D_name, D_colour, D_meets]) end end). chameneo(Name, Colour, Mall, Meets) -> Mall ! {join,self(),Name,Colour}, receive {meet,_,Other_Colour} -> chameneo(Name, new_colour(Colour, Other_Colour), Mall, Meets+1) ; {quit} -> Mall ! {done,Name,Colour,Meets} end. new_colour(red, red ) -> red; new_colour(red, blue ) -> yellow; new_colour(red, yellow) -> blue; new_colour(blue, red ) -> yellow; new_colour(blue, blue ) -> blue; new_colour(blue, yellow) -> red; new_colour(yellow, red ) -> blue; new_colour(yellow, blue ) -> red; new_colour(yellow, yellow) -> yellow. %----------------------------------------------------------------------- % The following functions are provided here for clarity. % Such functions are normally obtained from the library. % mapi([X1,...,Xn], F) => [F(1,X1),...,F(n,Xn)] mapi(L, F) -> mapi_loop(L, 0, F). mapi_loop([X|Xs], I, F) -> J = I+1, [F(J, X) | mapi_loop(Xs, J, F)]; mapi_loop([], _, _) -> []. % for(L, U, F) calls F(L), F(L+1), ..., F(U), discarding the results. for(L, U, _) when L > U -> ok; for(L, U, F) -> F(L), for(L+1, U, F). % for_each([X1,...,Xn], F) calls F(X1), ..., F(Xn), discarding the results. for_each([X|Xs], F) -> F(X), for_each(Xs, F); for_each([], _) -> ok.