COVERAGE SUMMARY
FILE SUMMARY
NameExecutedRoutines%ExecutedLines%Unexecuted
/home/matt/eu/rds/include/std/primes.e33100.00%626595.38%3
ROUTINE SUMMARY
RoutineExecutedLinesUnexecuted
calc_primes()404295.24%2
prime_list()8988.89%1
next_prime()1313100.00%0
LINE COVERAGE DETAIL
#Executed
1
-- (c) Copyright - See License.txt
2
--
3
namespace primes
4
5
--****
6
-- == Prime Numbers
7
-- **Page Contents**
8
--
9
-- <>
10
11
include std/search.e
12
1321
sequence list_of_primes = {2,3} -- Initial seedings.
14
15
--****
16
-- === Routines
17
--
18
19
--**
20
-- Returns all the prime numbers below some threshold, with a cap on computation time.
21
--
22
-- Parameters:
23
-- # ##max_p## : an integer, the last prime returned is the next prime after or on this value.
24
-- # ##time_out_p## : an atom, the maximum number of seconds that this function can run for.
25
-- The default is 10 (ten) seconds.
26
--
27
-- Returns:
28
-- A **sequence**, made of prime numbers in increasing order. The last value is
29
-- the next prime number that falls on or after the value of ##max_p##.
30
--
31
-- Comments:
32
-- * The returned sequence contains all the prime numbers less than its last element.
33
--
34
-- * If the function times out, it may not hold all primes below ##max_p##,
35
-- but only the largest ones will be absent. If the last element returned is
36
-- less than ##max_p## then the function timed out.
37
--
38
-- * To disable the timeout, simply give it a negative value.
39
--
40
-- Example 1:
41
--
42
-- ? calc_primes(1000, 5)
43
-- -- On a very slow computer, you may only get all primes up to say 719.
44
-- -- On a faster computer, the last element printed out will be 997.
45
-- -- This call will never take longer than 5 seconds.
46
--
47
--
48
-- See Also:
49
-- [[:next_prime]] [[:prime_list]]
5021
51
sequence result_
52
integer candidate_
53
integer pos_
54
atom time_out_
55
integer maxp_
56
integer maxf_
57
integer maxf_idx
58
integer next_trigger
59
60
-- First we check to see if we have already got the requested value.
6121
if max_p <= list_of_primes[$] then
621
pos_ = binary_search(max_p, list_of_primes)
631
if pos_ < 0 then
640
pos_ = (-pos_) + 1
65
end if
66
-- Already got it.
671
return list_of_primes[1..pos_]
68
end if
69
70
-- Record the largest known prime (so far) and its index.
7120
pos_ = length(list_of_primes)
7220
candidate_ = list_of_primes[$]
73
74
-- Calculate the largest possible factor for the largest known prime, and its index.
7520
maxf_ = floor(power(candidate_, 0.5))
7620
maxf_idx = binary_search(maxf_, list_of_primes)
7720
if maxf_idx < 0 then
7817
maxf_idx = (-maxf_idx)
7917
maxf_ = list_of_primes[maxf_idx]
80
end if
81
-- Calculate what the trigger is for when we need to go to the next maximum factor value.
8220
next_trigger = list_of_primes[maxf_idx+1]
8320
next_trigger *= next_trigger
84
85
-- Pre-allocate space for the new values. This allocates more than we will
86
-- need so the return value takes a slice up to the last stored prime.
8720
result_ = list_of_primes & repeat(0, floor(max_p / 3.5) - length(list_of_primes))
88
89
-- Calculate when we must stop running. A negative value is really equivalent
90
-- to a little over three years from now.
9120
if time_limit_p < 0 then
920
time_out_ = time() + 100_000_000
93
else
9420
time_out_ = time() + time_limit_p
95
end if
96
9720
while time_out_ >= time() label "MW" do
98
-- As this could run for a significant amount of time,
99
-- yield to any other tasks that might be ready.
10098758
task_yield()
101
102
-- Get the next candidate value to examine.
10398758
candidate_ += 2
104
105
-- If this is at or past the factor trigger point
106
-- pluck out the next maximum factor and calculate
107
-- the next trigger.
10898758
if candidate_ >= next_trigger then
109117
maxf_idx += 1
110117
maxf_ = result_[maxf_idx]
111117
next_trigger = result_[maxf_idx+1]
112117
next_trigger *= next_trigger
113
end if
114
115
-- Examine the candidate.
11698758
for i = 2 to pos_ do
117
-- If this potential factor is larger than the 'maximum' factor
118
-- then we don't need to examine any more. The candidate is a prime.
1191463812
maxp_ = result_[i]
1201463812
if maxp_ > maxf_ then
12118393
exit
122
end if
123
124
-- If it is divisible by any known prime then
125
-- we go get another candidate value.
1261445419
if remainder(candidate_, maxp_) = 0 then
12780365
continue "MW"
128
end if
1291365054
end for
130
131
-- Store it in the result, making sure that the result sequence is larger enough.
13218393
pos_ += 1
13318393
if pos_ >= length(result_) then
13414
result_ &= repeat(0, 1000)
135
end if
13618393
result_[pos_] = candidate_
137
138
-- If the value just stored is larger or equal to the requested value
139
-- then we can stop running.
14018393
if candidate_ >= max_p then
14117
exit
142
end if
14318376
end while
144
14520
return result_[1..pos_]
146
end function
147
148
149
--**
150
-- Return the next prime number on or after the supplied number
151
--
152
-- Parameters:
153
-- # ##n## : an integer, the starting point for the search
154
-- # ##fail_signal_p## : an integer, used to signal error. Defaults to -1.
155
--
156
-- Returns:
157
-- An **integer**, which is prime only if it took less than 1 second
158
-- to determine the next prime greater or equal to ##n##.
159
--
160
-- Comments:
161
-- The default value of -1 will alert you about an invalid returned value,
162
-- since a prime not less than ##n## is expected. However, you can pass
163
-- another value for this parameter.
164
--
165
-- Example 1:
166
--
167
-- ? next_prime(997)
168
-- -- On a very slow computer, you might get -997, but 1003 is expected.
169
--
170
--
171
-- See Also:
172
-- [[:calc_primes]]
173
17474
175
integer i
176
17774
if n < 0 then
1781
return fail_signal_p
179
end if
18073
if list_of_primes[$] < n then
18119
list_of_primes = calc_primes(n,time_out_p)
182
end if
18373
if n > list_of_primes[$] then
1843
return fail_signal_p
185
end if
186
-- Assumes that most searches will be less than about 1000
18770
if n < 1009 and 1009 <= list_of_primes[$] then
18817
i = binary_search(n, list_of_primes, ,169)
189
else
19053
i = binary_search(n, list_of_primes)
191
end if
19270
if i < 0 then
19319
i = (-i)
194
end if
19570
return list_of_primes[i]
196
197
end function
198
199
--**
200
-- Returns a list of prime numbers.
201
--
202
-- Parameters:
203
-- # ##top_prime_p## : The list will end with the prime less than or equal
204
-- to this value. If this is zero, the current list calculated primes
205
-- is returned.
206
--
207
-- Returns:
208
-- An **sequence**, a list of prime numbers from 2 to ##top_prime_p##
209
--
210
-- Example 1:
211
--
212
-- sequence pList = prime_list(1000)
213
-- -- pList will now contain all the primes from 2 up to the largest less than or
214
-- -- equal to 1000.
215
--
216
--
217
-- See Also:
218
-- [[:calc_primes]], [[:next_prime]]
219
--
2209
221
integer index_
222
2239
if top_prime_p <= 0 then
2248
return list_of_primes
225
end if
226
2271
if list_of_primes[$] < top_prime_p then
2281
list_of_primes = calc_primes(top_prime_p, 5)
229
end if
230
2311
index_ = binary_search(top_prime_p, list_of_primes)
2321
if index_ < 0 then
2330
index_ = - index_
234
end if
235
2361
return list_of_primes[1 .. index_]
237
end function