[erlang-questions] Generating Primes and the O'Neill paper
Angel Alvarez
<>
Wed Dec 16 23:29:43 CET 2009
El Miércoles, 16 de Diciembre de 2009 James Aimonetti escribió:
> I have been working the Project Euler problems and wanted to see what
> the list thought about my implementation of a prime number generator
> that is based off the Melissa O'Neill paper[1]. I also used a lazy list
> idea from one of Joe Armstrong's suggestions[2] concerning a Euler
> problem. My implementation uses the priority queue (page 7 of the PDF),
> and I'm using a skew heap I found[3] on this list to accomplish that,
> which I modified to handle key-value pairs instead of just keys.
>
> I made a pastie[4] to view the code.
>
> I tried to stay true to the Haskell version in the paper but had to
> modify some parts. I don't know Haskell so I easily could have lost
> something in the translation.
>
> Oh, the function is called queue because I was playing with other
> methods, like the unfaithful sieve, but I've only included the queue/1
> in the pastie. I am going to try the wheel and other optimizations
> talked about in the paper, but wanted a sanity check from the gurus that
> my Erlang is decent and the implementation isn't totally bunk.
>
> Thanks in advance for any advice or corrections.
>
> [1] - http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf
> [2] - http://www.erlang.org/cgi-bin/ezmlm-cgi?4:mss:177:khdaceipfabbicmifdhf
> [3] -
> http://www.erlang.org/pipermail/erlang-questions/2007-August/028769.html
> [4] - http://pastie.org/746050
>
Hi this paper is very interesting, but being novice icant hardly say you
something about your code. Maybe you can check mine for a
multiprocess approach.
Ive include my try on this "genuine" erathostenes sieve.
every worker stores one prime and properly crosses off on the fly when the numbers
are testet. Its a kind of lazy as it creates new worker in demand...
With my code you can do a naive exercise:
:~/Documents/Personal/Erlang/Code/primality> erlc multi_erathostenes.erl
:~/Documents/Personal/Erlang/Code/primality> erl
Erlang R13B01 (erts-5.7.2) [source] [rq:1] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.7.2 (abort with ^G)
1> OnePID=spawn(multi_erathostenes,worker,[2,4]).
<0.35.0>
2> [ OnePID ! {test,X} || X <- [3,4,5,6,7,8,9,10,11]].
[Worker of prime: 2 (4)] Spawn new worker for Prime: 3
[Worker of prime: 2 (4)] Found composite: 4
[Worker of prime: 2 (6)] passing along: 5
[Worker of prime: 2 (6)] Found composite: 6
[Worker of prime: 3 (9)] Spawn new worker for Prime: 5
[Worker of prime: 2 (8)] passing along: 7
[Worker of prime: 2 (8)] Found composite: 8
[Worker of prime: 3 (9)] passing along: 7
[Worker of prime: 2 (10)] passing along: 9
[Worker of prime: 5 (25)] Spawn new worker for Prime: 7
[Worker of prime: 2 (10)] Found composite: 10
[Worker of prime: 3 (9)] Found composite: 9
[Worker of prime: 2 (12)] passing along: 11
[Worker of prime: 3 (12)] passing along: 11
[Worker of prime: 5 (25)] passing along: 11
[Worker of prime: 7 (49)] Spawn new worker for Prime: 11
/Angel
--
Agua para todo? No, Agua para Todos.
->>-----------------------------------------------
Clist UAH a.k.a Angel
---------------------------------[www.uah.es]-<<--
-------------- next part --------------
% Multi "Genuine" Erathostenes
% 02 03 05 07 11 13 17
% P 02 -> 04
% P 03 04 -> 09
% C 04 == 04 09
% P 05 06 09 -> 25
% C 06 == 06 09 25
% P 07 08 09 25 -> 49
% C 08 == 08 09 25 49
% C 09 10 == 09 25 49
% C 10 == 10 12 25 49
% P 11 12 12 25 49 -> 121
% C 12 == 12 == 12 25 49 121
% P 13 14 15 25 49 121 -> 169
% C 14 == 14 15 25 49 121 169
% C 15 16 == 15 25 49 121 169
% C 16 == 16 18 25 49 121 169
% P 17 18 18 25 49 121 169 -> 289
-module(multi_erathostenes).
-compile(export_all).
worker(Prime,UpperBound)->
receive
{test,Number} ->
case Number == UpperBound of
true ->
io:format("[Worker of prime: ~w (~w)] Found composite: ~w~n",[Prime,UpperBound,Number]),
worker(Prime,UpperBound + Prime);
false ->
io:format("[Worker of prime: ~w (~w)] Spawn new worker for Prime: ~w~n",[Prime,UpperBound,Number]),
NextPID =spawn(?MODULE,worker,[Number,Number*Number]),
worker(Prime,UpperBound,NextPID)
end
end.
worker(Prime,UpperBound,NextPID) ->
receive
{test,Number} ->
case Number == UpperBound of
true ->
io:format("[Worker of prime: ~w (~w)] Found composite: ~w~n",[Prime,UpperBound,Number]),
worker(Prime,UpperBound + Prime,NextPID);
false ->
io:format("[Worker of prime: ~w (~w)] passing along: ~w~n",[Prime,UpperBound,Number]),
NextPID ! {test,Number},
worker(Prime,UpperBound,NextPID)
end
end.
% main(LimiteSuperior) ->
% FirstWorkerPID = spawn(?MODULE, worker,[2,4]),
% PID_Generador = spawn(?MODULE, generador_inicial, [LimiteSuperior,self()]),
% PID_Worker = pool:pspawn(?MODULE, worker,[1,PID_Acumulador,?MAXPRIMES,[] ]),
% T1 = erlang:now(),
% Alimentador_PID = spawn(?MODULE, alimentador,[PID_Generador,PID_Worker]),
% PID_Generador ! done,
% receive
% {primes,Numero,Lista} ->
% io:format("[Main] Parando proceso [Acumulador]!~n"),
% PID_Acumulador ! done
% end,
% Total = lists:foldl( fun(X,Acc) -> Acc + X end,0,Lista),
% T2 = erlang:now(),
% T = timer:now_diff(T2,T1),
% io:format("[Main] Calcular la suma de los ~w primos hasta ~w : ~w ~n ha tomado ~w microsegundos~n",[Numero,LimiteSuperior,Total,T]).
More information about the erlang-questions
mailing list