三角数の約数(2)

30分プログラム、その272。三角数の約数 via Project Euler、その2。
分散計算しようと思ったらErlangのビルドに予想以上に時間がかかっているので、昨日(id:mzp:20080326)のやつに途中キャンセルの機能などを追加してみた。

使い方

1> problem12:start().
7

ソースコード

-module(problem12).
-export([start/0]).

divisor_count(N)->
    length(lists:filter(fun(X)-> N rem X =:= 0 end,
			lists:seq(1,N))).

tri(N) -> N*(N+1) div 2.

loop(Pid,Target,N,Step)->
    receive
	M when M < N -> Pid ! {self(),M}
    after 0->
	    case divisor_count(tri(N)) >= Target of
		true ->
		    Pid ! {self(),N};
		_ ->
		    loop(Pid,Target,N+Step,Step)
	    end
    end.

run(S,Target,Start,Step) ->
    spawn(fun()->loop(S,Target,Start,Step) end).

wait_for_response([],R)->R;
wait_for_response(L,R)->
    receive
	{Pid,N} ->
	    % io:format("~p~n",[N]),
	    L2 = lists:delete(Pid,L),
	    lists:foreach(fun (X) -> X ! N end,L2),
	    wait_for_response(L2,[N|R])
    end.

start()->
    S = self(),
    Target = 10,
    P1 = run(S,Target,2,3),
    P2 = run(S,Target,3,3),
    P3 = run(S,Target,4,3),
    lists:min(wait_for_response([P1,P2,P3],[])).