Skip to content

Commit 3a0ef35

Browse files
committed
Begin work on exercise 23.2
1 parent 8d463df commit 3a0ef35

File tree

5 files changed

+239
-0
lines changed

5 files changed

+239
-0
lines changed

‎chapter_23/exercise_2/.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
_build

‎chapter_23/exercise_2/rebar.config‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{deps, []}.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
%% ---
2+
%% Excerpted from "Programming Erlang, Second Edition",
3+
%% published by The Pragmatic Bookshelf.
4+
%% Copyrights apply to this code. It may not be used to create training material,
5+
%% courses, books, articles, and the like. Contact us if you are in doubt.
6+
%% We make no guarantees that this code is fit for any purpose.
7+
%% Visit http://www.pragmaticprogrammer.com/titles/jaerlang2 for more book information.
8+
%%---
9+
-module(lib_primes).
10+
-export([make_prime/1, is_prime/1, make_random_int/1]).
11+
12+
make_prime(1) ->%% <label id="make_primes1" />
13+
lists:nth(random:uniform(4), [2,3,5,7]);
14+
make_prime(K) whenK>0->%% <label id="make_primes2" />
15+
new_seed(),
16+
N=make_random_int(K),
17+
ifN>3 ->
18+
io:format("Generating a ~w digit prime ",[K]),
19+
MaxTries=N-3,
20+
P1=make_prime(MaxTries, N+1),
21+
io:format("~n",[]),
22+
P1;
23+
true ->
24+
make_prime(K)
25+
end. %% <label id="make_primes3" />
26+
27+
make_prime(0, _) ->%% <label id="prime_loop1" />
28+
exit(impossible);
29+
make_prime(K, P) ->
30+
io:format(".",[]),
31+
caseis_prime(P) of
32+
true -> P;
33+
false -> make_prime(K-1, P+1)
34+
end. %% <label id="prime_loop2" />
35+
36+
is_prime(D) whenD<10->
37+
lists:member(D, [2,3,5,7]);
38+
is_prime(D) ->
39+
new_seed(),
40+
is_prime(D, 100).
41+
42+
is_prime(D, Ntests) ->
43+
N=length(integer_to_list(D)) -1,
44+
is_prime(Ntests, D, N).
45+
46+
is_prime(0, _, _) ->true; %% <label id="is_prime_1" />
47+
is_prime(Ntest, N, Len) ->%% <label id="is_prime_2" />
48+
K=random:uniform(Len),
49+
%% A is a random number less than K
50+
A=make_random_int(K),
51+
if
52+
A<N ->
53+
caselib_lin:pow(A,N,N) of
54+
A -> is_prime(Ntest-1,N,Len);
55+
_ -> false
56+
end;
57+
true ->
58+
is_prime(Ntest, N, Len)
59+
end. %% <label id="is_prime_3" />
60+
61+
%% make_random_int(N) -> a random integer with N digits.
62+
make_random_int(N) ->new_seed(), make_random_int(N, 0). %% <label id="make_ran_int1" />
63+
64+
make_random_int(0, D) ->D;
65+
make_random_int(N, D) ->
66+
make_random_int(N-1, D*10+ (random:uniform(10)-1)). %% <label id="make_ran_int2" />
67+
68+
69+
70+
%END:make_ran_int
71+
72+
new_seed() ->
73+
{_,_,X} =erlang:now(),
74+
{H,M,S} =time(),
75+
H1=H*Xrem32767,
76+
M1=M*Xrem32767,
77+
S1=S*Xrem32767,
78+
put(random_seed,{H1,M1,S1}).
79+
80+
81+
82+
83+
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
%%%-------------------------------------------------------------------
2+
%%% @doc
3+
%%% Prime tester gen server implementation. This gen server is the
4+
%%% actual worker process that performs the computation to determine
5+
%%% if the number is prime.
6+
%%% @end
7+
%%%-------------------------------------------------------------------
8+
-module(prime_tester_worker).
9+
10+
-behaviour(gen_server).
11+
12+
%% API
13+
-export([start_link/0, is_prime/1]).
14+
15+
%% gen_server callbacks
16+
-export([init/1,
17+
handle_call/3,
18+
handle_cast/2,
19+
handle_info/2,
20+
terminate/2,
21+
code_change/3]).
22+
23+
-define(SERVER, ?MODULE).
24+
25+
-record(state,{}).
26+
27+
%%%===================================================================
28+
%%% API
29+
%%%===================================================================
30+
31+
%%--------------------------------------------------------------------
32+
%% @doc
33+
%% Starts the server
34+
%%
35+
%% @spec start_link() ->{ok, Pid} | ignore |{error, Error}
36+
%% @end
37+
%%--------------------------------------------------------------------
38+
start_link() ->
39+
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
40+
41+
is_prime(Number) whenis_integer(Number) ->
42+
gen_server:call(?MODULE,{is_prime, Number}).
43+
44+
%%%===================================================================
45+
%%% gen_server callbacks
46+
%%%===================================================================
47+
48+
%%--------------------------------------------------------------------
49+
%% @private
50+
%% @doc
51+
%% Initializes the server
52+
%%
53+
%% @spec init(Args) ->{ok, State} |
54+
%%{ok, State, Timeout} |
55+
%% ignore |
56+
%%{stop, Reason}
57+
%% @end
58+
%%--------------------------------------------------------------------
59+
init([]) ->
60+
{ok, #state{}}.
61+
62+
%%--------------------------------------------------------------------
63+
%% @private
64+
%%--------------------------------------------------------------------
65+
handle_call({is_prime, Number}, _From, State) ->
66+
% Invoke lib_primes:is_prime to determine if the number is prime or not
67+
Result=lib_primes:is_prime(Number),
68+
{reply,{ok, Result}, State};
69+
70+
handle_call(_Request, _From, State) ->
71+
Reply=ok,
72+
{reply, Reply, State}.
73+
74+
%%--------------------------------------------------------------------
75+
%% @private
76+
%%--------------------------------------------------------------------
77+
handle_cast(_Msg, State) ->
78+
{noreply, State}.
79+
80+
%%--------------------------------------------------------------------
81+
%% @private
82+
%%--------------------------------------------------------------------
83+
handle_info(_Info, State) ->
84+
{noreply, State}.
85+
86+
%%--------------------------------------------------------------------
87+
%% @private
88+
%%--------------------------------------------------------------------
89+
terminate(_Reason, _State) ->
90+
ok.
91+
92+
%%--------------------------------------------------------------------
93+
%% @private
94+
%%--------------------------------------------------------------------
95+
code_change(_OldVsn, State, _Extra) ->
96+
{ok, State}.
97+
98+
%%%===================================================================
99+
%%% Internal functions
100+
%%%===================================================================
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
%%%-------------------------------------------------------------------
2+
%%% @doc
3+
%%%
4+
%%% @end
5+
%%%-------------------------------------------------------------------
6+
-module(prime_tester_worker_sup).
7+
8+
-behaviour(supervisor).
9+
10+
%% API
11+
-export([start_link/0]).
12+
13+
%% Supervisor callbacks
14+
-export([init/1]).
15+
16+
-define(SERVER, ?MODULE).
17+
18+
%%%===================================================================
19+
%%% API functions
20+
%%%===================================================================
21+
22+
%%--------------------------------------------------------------------
23+
%% @doc
24+
%% Starts the supervisor
25+
%%
26+
%% @end
27+
%%--------------------------------------------------------------------
28+
29+
start_link() ->
30+
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
31+
32+
%%%===================================================================
33+
%%% Supervisor callbacks
34+
%%%===================================================================
35+
36+
%%--------------------------------------------------------------------
37+
%% @private
38+
%%--------------------------------------------------------------------
39+
40+
init([]) ->
41+
MaxRestart=5,
42+
MaxTime=3600,
43+
M=prime_tester_worker,
44+
F=start_link,
45+
A= [],
46+
47+
{ok,{{simple_one_for_one, MaxRestart, MaxTime},
48+
[{prime_tester_worker,
49+
{M,F,A},
50+
temporary, 5000, worker, [M]}]}}.
51+
52+
%%%===================================================================
53+
%%% Internal functions
54+
%%%===================================================================

0 commit comments

Comments
(0)