-module(hooligan). -export([start/0]). start() -> Loop = spawn(fun() -> loop(100, 1) end), spawn(fun() -> cleaner(Loop, 1, fun(X) -> X + 3 end) end), spawn(fun() -> start_hooligan(Loop) end). start_hooligan(Pid) -> {A1, A2, A3} = now(), random:seed(A1, A2, A3), Pid ! {hooligan_in, random:uniform(60)}, hooligan_out(Pid, 22). hooligan_in(Pid, 0) -> Pid ! {hooligan_done}; hooligan_in(Pid, Count) -> timer:sleep(300), Pid ! {hooligan_in, random:uniform(60)}, hooligan_out(Pid, Count). hooligan_out(Pid, Count) -> timer:sleep(60), Pid ! {hooligan_out}, hooligan_in(Pid, Count - 1). cleaner(Pid, X, Fun) -> timer:sleep(400), Pid ! {cleaner, X}, case X of 58 -> F = fun(N) -> N - 3 end; 1 -> F = fun(N) -> N + 3 end; _ -> F = Fun end, cleaner(Pid, F(X), F). loop(Hooligan, Cleaner) -> receive {hooligan_in, X} when Cleaner =:= X; Cleaner + 1 =:= X; Cleaner + 2 =:= X -> io:format("Hooligan is caught in ~p while cleaner in ~p~n", [X, Cleaner]); {hooligan_in, X} -> io:format("Hooligan in ~p~n", [X]), loop(X, Cleaner); {hooligan_out} -> io:format("Hooligan out~n"), loop(100, Cleaner); {hooligan_done} -> io:format("Hooligan done~n"); {cleaner, X} when X =:= Hooligan; X + 1 =:= Hooligan; X + 2 =:= Hooligan -> io:format("Hooligan is caught in ~p while cleaner in ~p~n", [Hooligan, X]); {cleaner, X} -> io:format("Cleaner in ~p~n", [X]), loop(Hooligan, X) end.