Skip to content

Instantly share code, notes, and snippets.

@kennethlakin
Last active December 15, 2015 00:49
Show Gist options
  • Save kennethlakin/5175264 to your computer and use it in GitHub Desktop.
Save kennethlakin/5175264 to your computer and use it in GitHub Desktop.
-module(coin).
-export([start/1, stop/0, coin/2, gather/2, gatherStatus/2]).
start(N) ->
Gatherpid = spawn(?MODULE, gather, [0, now()]),
register(gather, Gatherpid),
spawn(?MODULE, gatherStatus, [Gatherpid, 0]),
coin(N, Gatherpid).
stop() ->
whereis(gather) ! {quit}.
gatherStatus(Pid, Prevx) ->
timer:send_after(300, Pid, {status, Prevx}).
gather(X, Start) ->
receive
{status, Prevx} ->
if Prevx==X ->
End = now(),
io:format("Reached solution: ~w in ~w~n", [X, timer:now_diff(End, Start)/1000000]),
spawn(?MODULE, stop, []),
gather(X, Start);
true->
spawn(?MODULE, gatherStatus, [self(), X]),
gather(X, Start)
end;
{result, N} ->
gather(X+N, Start);
{quit} ->
io:format("Stopping.~n"),
ok
end.
coin(0, Pid) ->
Pid ! {result, 1};
coin(N, Pid) ->
coin(trunc(N/2), Pid),
coin(trunc(N/3), Pid),
coin(trunc(N/4), Pid).
-module(coin2).
-export([coin/2]).
coin(0) ->
1;
coin(N) ->
coin(trunc(N/2))+
coin(trunc(N/3))+
coin(trunc(N/4)).
coin(N, _) ->
Start=now(),
Res=coin(N),
End=now(),
[Res, timer:now_diff(End, Start)/1000000].
-module(coin3).
-export([start/1, stop/0, coincal/1, gather/0]).
start(N) ->
Gatherpid = spawn(?MODULE, gather, []),
register(gather, Gatherpid).
stop() ->
whereis(gather) ! {quit}.
gather() ->
receive
{result, N, Start, End} ->
io:format("Reached solution: ~w in ~w~n", [N, timer:now_diff(End, Start)/1000000]),
gather();
{quit} ->
io:format("Stopping.~n"),
ok
end.
coin(0) ->
1;
coin(N) ->
coin(trunc(N/2))+
coin(trunc(N/3))+
coin(trunc(N/4)).
coincal(N) ->
Start = now(),
Res = coin(N),
End = now(),
whereis(gather) ! { result, Res, Start, End }.
@kennethlakin
Copy link
Author

coin:start(10000000) finds a solution in ~7.8 seconds.

coin2:coin(10000000, 0) finds a solution in ~1.7 seconds, which is the same amount of time as a naive iterative C++ implementation.

I'm kinda disappointed that adding in some messaging makes such a large difference. Clearly, more thought is required.

Edit: coin3:coincal/1 is about the same speed as coin2:coin/2. Yep. Messaging is slow.

@rictic
Copy link

rictic commented Mar 16, 2013

What if you just spawned on the first call, giving you three threads of execution calculating, and only a little bit of startup and messaging overhead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment