Is there a faster way to find primes in lua? - lua

I am working on Project Euler, and my code is just taking way too long to compute. I am supposed to find the sum of all primes less than 2,000,000 , but my program would take years to complete. I would try some different ways to find primes, but the problem is that I only know one way.
Anyways, here is my code:
sum=2
flag=0
prime=3
while prime<2000000 do
for i=2,prime-1 do
if prime%i==0 then
flag=1
end
end
if flag==0 then
print(prime)
sum=sum+prime
end
prime=prime+1
flag=0
if prime==2000000 then
print(sum)
end
end
Does anyone know of any more ways to find primes, or even a way to optimize this? I always try to figure coding out myself, but this one is truly stumping me.
Anyways, thanks!

This code is based on Sieve of Eratosthenes.
Whenever a prime is found, its multiples are marked as non-prime. Remaining integers are primes.
nonprimes={}
max=2000000
sum=2
prime=3
while prime<max do
if not nonprimes[prime] then
-- found a prime
sum = sum + prime
-- marks multiples of prime
i=prime*prime
while i < max do
nonprimes[i] = true
i = i + 2*prime
end
end
-- primes cannot be even
prime = prime + 2
end
print(sum)
As an optimization, even numbers are never considered. It reduces array size and number of iterations by 2. This is also why considered multiple of a found prime are (2k+1)*prime.
Your program had some bugs and computing n^2 divisions is very expensive.

Related

Finding the number of digits in a number restricted number of tools since I am a Python beginner

def digits(n):
total=0
for i in range(0,n):
if n/(10**(i))<1 and n/(10**(i-1))=>1:
total+=i
else:
total+=0
return total
I want to find the number of digits in 13 so I do the below
print digits(13)
it gives me $\0$ for every number I input into the function.
there's nothing wrong with what I've written as far as I can see:
if a number has say 4 digits say 1234 then dividing by 10^4 will make it less than 1: 0.1234 and dividing by 10^3 will make it 1.234
and by 10^3 will make it 1.234>1. when i satisfies BOTH conditions you know you have the correct number of digits.
what's failing here? Please can you advise me on the specific method I've tried
and not a different one?
Remember for every n there can only be one i which satisfies that condition.
so when you add i to the total there will only be i added so total returning total will give you i
your loop makes no sense at all. It goes from 0 to exact number - not what you want.
It looks like python, so grab a solution that uses string:
def digits(n):
return len(str(int(n))) # make sure that it's integer, than conver to string and return number of characters == number of digits
EDIT:
If you REALLY want to use a loop to count number of digits, you can do this this way:
def digits(n):
i = 0
while (n > 1):
n = n / 10
++i
return i
EDIT2:
since you really want to make your solution work, here is your problem. Provided, that you call your function like digits(5), 5 is of type integer, so your division is integer-based. That means, that 6/100 = 0, not 0.06.
def digits(n):
for i in range(0,n):
if n/float(10**(i))<1 and n/float(10**(i-1))=>1:
return i # we don't need to check anything else, this is the solution
return null # we don't the answer. This should not happen, but still, nice to put it here. Throwing an exception would be even better
I fixed it. Thanks for your input though :)
def digits(n):
for i in range(0,n):
if n/(10**(i))<1 and n/(10**(i-1))>=1:
return i

Recurrence Relation tree method

I am currently having issues with figuring our some recurrence stuff and since I have midterms about it coming up soon I could really use some help and maybe an explanation on how it works.
So I basically have pseudocode for solving the Tower of Hanoi
TOWER_OF_HANOI ( n, FirstRod, SecondRod, ThirdRod)
if n == 1
move disk from FirstRod to ThirdRod
else
TOWER_OF_HANOI(n-1, FirstRod, ThirdRod, SecondRod)
move disk from FirstRod to ThirdRod
TOWER_OF_HANOI(n-1, SecondRod, FirstRod, ThirdRod)
And provided I understand how to write the relation (which, honestly I'm not sure I do...) it should be T(n) = 2T(n-1)+Ɵ(n), right? I sort of understand how to make a tree with fractional subproblems, but even then I don't fully understand the process that would give you the end solution of Ɵ(n) or Ɵ(n log n) or whatnot.
Thanks for any help, it would be greatly appreciated.
Assume the time complexity is T(n), it is supposed to be: T(n) = T(n-1) + T(n-1) + 1 = 2T(n-1) + 1. Why "+1" but not "+n"? Since "move disk from FirstRod to ThirdRod" costs you only one move.
For T(n) = 2T(n-1) + 1, its recursion tree will exactly look like this:
https://www.quora.com/What-is-the-complexity-of-T-n-2T-n-1-+-C (You might find it helpful, the image is neat.) C is a constant; it means the cost per operation. In the case of Tower of Hanoi, C = 1.
Calculate the sum of the cost each level, you will easily find out in this case, the total cost will be 2^n-1, which is exponential(expensive). Therefore, the answer of this recursion equation is Ɵ(2^n).

What is the time complexity of Ruby's built in #permutation and #repeated_permutation methods?

I've been wondering about the time complexity of some of Ruby's built-in methods, these two in particular. I think the best I've been able to come up with for a permutation method on my own is Θ(n · n!), does Ruby's built-in perform better? If so, please help me understand their algorithm.
Permutation
Array#permutation returns an Enumerator with n! Arrays, so the time complexity will be at least O(n!).
I wrote this method :
def slow_method(n)
(1..n).to_a.permutation.each do |p|
p
end
end
It doesn't do anything with p, expect forcing the generation of all the permutations. Building an Array of all the permutations would use too much memory.
This method was called 10 times for n between 10 and 13, and the average times in seconds were :
t10 = 0.618895
t11 = 6.7815425
t12 = 82.896605
t13 = 1073.015602
O(n!) looks like a reasonable approximation :
t13/fact(13)*fact(12)/t12 #=> 0.995694114280165
t13/fact(13)*fact(11)/t11 #=> 1.0142685297667369
t13/fact(13)*fact(10)/t10 #=> 1.0103498450722133
O(n*n!) doesn't :
t13/(fact(13)*13)*fact(12)*12/t12 #=> 0.9191022593355369
t13/(fact(13)*13)*fact(11)*11/t11 #=> 0.8582272174949312
t13/(fact(13)*13)*fact(10)*10/t10 #=> 0.777192188517087
The generation seems to be O(n!), but doing anything with the generated Arrays would bring the overall complexity to O(n*n!).
Why isn't the generation O(n*n!)? It could come from the fact that when recursively generating [1,2,3,4,5].permutation, the remaining permutations are the same for [1,2] and [2,1].
O(n!) is already so slow that n will never be much bigger than 10, so O(n*n!) isn't much worse. For n=20, n! is 2432902008176640000 and n*n! is 48658040163532800000.
Repeated Permutation
[1,2,...n].repeated_permutation(k) generates n**k Arrays of k elements.
The complexity should be either O(n**k) or O(k*n**k).
For k=n, it becomes O(n**n) or O(n**(n+1)), which is even (much) worse than for permutation.
There are algorithms to iteratively generate all permutations of a list.
How? The algorithm generates all permutations of [1,2,3,4,...,n] in lexicographic order. Given one permutation the algorithm generates the next lexicographic permutation in O(1) time.
These are the steps
Find the largest index k such that a[k] < a[k + 1], if no such index exists the permutation is the last permutation
Find the largest index l greater than k such that a[k] < a[l]
Swap the value of a[k] with that of a[l]
Reverse the sequence from a[k + 1] up to and including the final element a[n]
What is the complexity?
Each step is O(1) and there are O(n!) permutations, so the total complexity is O(n!).

How to solve project Euler #12 in Lua?

Ok, here it goes another Euler problem question.
I've started to learn Lua by solving Euler project problems and got stuck on Euler problem 12.
It looks to me very straightforward and I don't understand why is my result incorrect?
Here is my solution so far:
-- return triangular number of the specified number
function get_tri_num(num)
local n = 0
for i=1, num do
n = n + i
end
return n
end
-- return all factors of the specifeid number
function factors(num)
local factors = {}
for i=1, num/2 do
if num%i == 0 then
factors[#factors+1] = i
end
end
factors[#factors+1] = num
return factors
end
-- get the first triangle number with >500 divisors
function euler12()
local n = 0
local trinum = 1
while true do
n = n + 7
trinum = get_tri_num(n)
if #factors(trinum) > 500 then break end
end
print(trinum, n)
end
euler12()
This problem is computation intensive, well, at least the way I am solving it, so I use luajit.
time luajit euler12.lua
103672800 14399
real 3m14.971s
user 3m15.033s
sys 0m0.000s
First, I try this solution on the toy example provided in the problem description. Changing the line of euler12() to if #factors(trinum) > 5 then break end, I get:
28 7
Which corresponds to the results shown in the problem example.
Second, after I see that the toy example is working I run euler12() with >500 condition. According to my solution the answer is 103672800 and yes, if I separately check the number of divisors for this result is >500:
print(#factors(103672800))
648
But...
The problem is here:
while true do
n = n + 7
Why does n increaments 7 each time? That doesn't make sense, change it to 1, and you could get the correct answer.
However, the performance is still poor. Several places that could be improved:
Every time the function get_tri_num is called, it's calculating
from scratch, that's not necessary.
You don't need the factors of a number, you only need the number of
factors of a number, so why return a table in factors?
for i=1, num/2 do is not necessary. Iterating to the square root of
num is enough to get the number of factors.
Refer to my code for the same problem.

Project Euler #3 Ruby Solution - What is wrong with my code?

This is my code:
def is_prime(i)
j = 2
while j < i do
if i % j == 0
return false
end
j += 1
end
true
end
i = (600851475143 / 2)
while i >= 0 do
if (600851475143 % i == 0) && (is_prime(i) == true)
largest_prime = i
break
end
i -= 1
end
puts largest_prime
Why is it not returning anything? Is it too large of a calculation going through all the numbers? Is there a simple way of doing it without utilizing the Ruby prime library(defeats the purpose)?
All the solutions I found online were too advanced for me, does anyone have a solution that a beginner would be able to understand?
"premature optimization is (the root of all) evil". :)
Here you go right away for the (1) biggest, (2) prime, factor. How about finding all the factors, prime or not, and then taking the last (biggest) of them that is prime. When we solve that, we can start optimizing it.
A factor a of a number n is such that there exists some b (we assume a <= b to avoid duplication) that a * b = n. But that means that for a <= b it will also be a*a <= a*b == n.
So, for each b = n/2, n/2-1, ... the potential corresponding factor is known automatically as a = n / b, there's no need to test a for divisibility at all ... and perhaps you can figure out which of as don't have to be tested for primality as well.
Lastly, if p is the smallest prime factor of n, then the prime factors of n are p and all the prime factors of n / p. Right?
Now you can complete the task.
update: you can find more discussion and a pseudocode of sorts here. Also, search for "600851475143" here on Stack Overflow.
I'll address not so much the answer, but how YOU can pursue the answer.
The most elegant troubleshooting approach is to use a debugger to get insight as to what is actually happening: How do I debug Ruby scripts?
That said, I rarely use a debugger -- I just stick in puts here and there to see what's going on.
Start with adding puts "testing #{i}" as the first line inside the loop. While the screen I/O will be a million times slower than a silent calculation, it will at least give you confidence that it's doing what you think it's doing, and perhaps some insight into how long the whole problem will take. Or it may reveal an error, such as the counter not changing, incrementing in the wrong direction, overshooting the break conditional, etc. Basic sanity check stuff.
If that doesn't set off a lightbulb, go deeper and puts inside the if statement. No revelations yet? Next puts inside is_prime(), then inside is_prime()'s loop. You get the idea.
Also, there's no reason in the world to start with 600851475143 during development! 17, 51, 100 and 1024 will work just as well. (And don't forget edge cases like 0, 1, 2, -1 and such, just for fun.) These will all complete before your finger is off the enter key -- or demonstrate that your algorithm truly never returns and send you back to the drawing board.
Use these two approaches and I'm sure you'll find your answers in a minute or two. Good luck!
Do you know you can solve this with one line of code in Ruby?
Prime.prime_division(600851475143).flatten.max
=> 6857

Resources