This code works great. But it becomes incredibly slow when needing to reach into those highest numbers. I was able to get the 9500th prime using this.
Making sure to refer to the list as “a reference to” in applescript helped speed things up. But I still think I need a new approach.
set all_int to {}
set all_int_ref to a reference to all_int
set primes_list to {}
set primes_list_ref to a reference to primes_list
set bound to 10000
set t to (time of (current date))
repeat with i from 1 to bound
copy i to the end of all_int_ref
end repeat
set j to 2
repeat while j < (bound - 1)
if item j of all_int_ref is not false then
copy item j of all_int_ref to the end of primes_list_ref
try
repeat with n from 2 to bound
set item (j * n) of all_int_ref to false
end repeat
end try
end if
set j to j + 1
end repeat
log ((time of (current date)) - t)
log (count primes_list)
return primes_list
Trying to use google to find a list of the first 15000 consecutive integers found nothing. Generating this list on my own was fast, only a few seconds. But using this list gave a “stack overflow” error.
This next script worked to make the list of consecutive numbers smaller with each repeat. While it worked great with bound=10,000 it was still not powerful enough to handle the number sizes I need.
set all_int to {}
set all_int_ref to a reference to all_int
set primes_list to {}
set primes_list_ref to a reference to primes_list
set bound to 100000
set t to (time of (current date))
repeat with i from 2 to bound
copy i to the end of all_int_ref
end repeat
repeat
if item 1 of all_int_ref is not false then
copy (item 1 of all_int_ref) to this_prime
copy this_prime to the end of primes_list_ref
try
repeat with n from 1 to bound
set item ((this_prime * n) + 1) of all_int_ref to false
end repeat
end try
end if
try
copy (items 2 thru (count all_int_ref) of all_int_ref) to all_int
on error
exit repeat
end try
end repeat
log ((time of (current date)) - t)
log (count primes_list)
log primes_list
try
return item 10001 of primes_list
end try
I feel like I am getting no closer to the answer than when I began. I’ve added timing counts into the script so I can see how changes in it effect the load. It seems like the changes I’ve been making aren’t making it any more efficient. Time for a new strategy.
set all_int to {}
set all_int_ref to a reference to all_int
set primes_list to {}
set primes_list_ref to a reference to primes_list
set new_int to {}
set new_int_ref to a reference to new_int
set bound to 30000
set half_bound to (bound / 2)
set t to (time of (current date))
repeat with i from 2 to bound
copy i to the end of all_int_ref
end repeat
repeat
--log all_int
if (item 1 of all_int) < half_bound then
set this_prime to (item 1 of all_int_ref)
copy this_prime to the end of primes_list_ref
repeat with m from 1 to (count all_int_ref)
copy (item m of all_int_ref) to n
if ((n / this_prime) mod 1 is not 0) and (n is not this_prime) then copy n to the end of new_int_ref
end repeat
copy new_int to all_int
set new_int to {}
else
log ((time of (current date)) - t)
return primes_list_ref & all_int_ref
end if
end repeat
--log ((time of (current date)) - t)
--log (count primes_list_ref)
return primes_list
try
return item 10001 of primes_list
end try
This script has managed to cut 5 seconds off the time to evaluate 50,000 integers. I’m hoping that will be enough of a difference when it comes to the biggest numbers. My strategy was to cut down the number of “repeat” statements I’m using, thus cutting the amount of computation. I used a handler that evaluates if an integer is prime or not. This way, I don’t have to create the big list of integers first, because a repeat statement already has ordered integers built in to it.
It’s good!
set primes_list to {}
set primes_list_ref to a reference to primes_list
set t to (time of (current date))
repeat with this_num from 2 to 150000
copy is_this_prime(this_num, primes_list_ref) to this_eval
if this_eval is not {} then copy this_eval to the end of primes_list_ref
if (count (primes_list_ref)) = 10001 then return item 10001 of primes_list_ref
end repeat
to is_this_prime(a_num, primes_list)
repeat with a_prime in primes_list
if (a_num / a_prime mod 1 is 0) then
return {}
end if
end repeat
return a_num
end is_this_prime
log ((time of (current date)) - t)
log (count primes_list_ref)
return primes_list