Skip to content

Instantly share code, notes, and snippets.

@yoichiro
Created September 9, 2011 01:10
Show Gist options
  • Save yoichiro/1205237 to your computer and use it in GitHub Desktop.
Save yoichiro/1205237 to your computer and use it in GitHub Desktop.
ランダムに並んだ数列のANDを取るプログラム
-module(np).
-export([main/0]).
-define(LIST_LENGTH, 100).
main() ->
Source = create_test_list(?LIST_LENGTH),
product_all_lists(Source, 0).
product_all_lists([], Count) ->
receive_product_lists_result([], 0, Count);
product_all_lists([L1], Count) ->
receive_product_lists_result([L1], 0, Count);
product_all_lists([L1, L2 | T], Count) ->
Pid = self(),
spawn_link(fun() ->
product_lists(Pid, [L1, L2])
end),
product_all_lists(T, Count + 1).
receive_product_lists_result([L1], Count, Limit) when Count == Limit ->
io:format("Result: ~p~n", [L1]);
receive_product_lists_result(Result, Count, Limit) when Count == Limit ->
product_all_lists(Result, 0);
receive_product_lists_result(Result, Count, Limit) ->
receive
List ->
receive_product_lists_result([List | Result], Count + 1, Limit)
end.
product_lists(ParentPid, [L1, L2]) ->
Result = product_lists(L1, L2, []),
ParentPid ! Result.
product_lists([], _, Result) ->
Result;
product_lists([H | T], L2, Result) ->
case lists:member(H, L2) of
true ->
product_lists(T, L2, [H | Result]);
false ->
product_lists(T, L2, Result)
end.
%% Creating test data.
create_test_list(Length) ->
Seq = lists:seq(1, Length),
create_test_list(Seq, [], Length, 0).
create_test_list(_, Result, Length, Count) when Length == Count ->
Result;
create_test_list(Seq, Result, Length, Count) ->
Sorted = create_rand_list(Seq),
create_test_list(Seq, [Sorted | Result], Length, Count + 1).
create_rand_list(Source) ->
create_rand_list(Source, []).
create_rand_list([], Result) ->
Length = crypto:rand_uniform(?LIST_LENGTH - 5, ?LIST_LENGTH),
lists:sublist(Result, Length);
create_rand_list(Source, Result) ->
Length = length(Source),
Position = crypto:rand_uniform(0, Length),
Value = get_value_at(Source, Position),
create_rand_list(lists:delete(Value, Source), [Value | Result]).
get_value_at(Source, Position) ->
get_value_at(Source, Position, 0).
get_value_at([], _, _) ->
throw("Position too big.");
get_value_at([H | _], Position, Count) when Position == Count ->
H;
get_value_at([_ | T], Position, Count) ->
get_value_at(T, Position, Count + 1).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment