Fast prime numbers between range - c#

I am trying to develop one program for develop very fast prime numbers. Prime numbers are to be generated in range (Range <= 10000) and the result should be printed in under 6 seconds. This is the program i have made so far. It runs just fine on my machine 1.73 core 2 duo and produces result in under 3 seconds. But when i submit it to online program submission validator it gives time limit exceeded. I have even removed try catch block etc as i thought removing try catch may save few resources and buy me few milliseconds, but no matter whatever i do i always get time limit exceeded. This is my code :-
using System;
using System.Collections.Generic;
using System.Linq;
namespace PrimeNumberGenerator
{
class Program
{
static void Main(string[] args)
{
int T = Convert.ToInt32(Console.ReadLine());
List<string> listInput = new List<string>();
for (int i = 0; i < T; i++)
listInput.Add(Console.ReadLine());
for (int i = 0; i < T; i++)
{
string[] str = listInput[i].Split(' ');
int M = Convert.ToInt32(str[0]);
int N = Convert.ToInt32(str[1]);
if ((N - M) <= 100000 && M >= 1 && M <= 1000000000 && N >= 1 && N <= 1000000000)
{
int[] list = Enumerable.Range(M, (N - M + 1)).ToArray();
int k = 2;
while (true)
{
if ((k * k) > N)
break;
for(int j = 0 ; j < list.Count() ;j++)
{
if (list[j] != k && (list[j] % k) == 0 && list[j] != 1 && list[j] != -1)
list[j] = -1;
}
k++;
}
foreach (int item in list)
{
if (item != -1)
Console.WriteLine(item);
}
}
else
Console.WriteLine("Limit exceeded");
}
}
}
}
You have to give input like this :-
1
2 30
1 is no of test case and 2 and 30 mean that all primes between 2 and 30 should be produced.
You can give it 1 if you are only testing it once. I will be very grateful if you can optimise this program
Thanks in advance :)
EDIT :-
This is the original implmentation that i thought but obviously has overhead of list :-
using System;
using System.Collections.Generic;
using System.Linq;
namespace PrimeNumberGenerator
{
class Program
{
static void Main(string[] args)
{
try
{
int T = Convert.ToInt32(Console.ReadLine());
List<string> listInput = new List<string>();
for (int i = 0; i < T; i++)
listInput.Add(Console.ReadLine());
for (int i = 0; i < T; i++)
{
string[] str = listInput[i].Split(' ');
int M = Convert.ToInt32(str[0]);
int N = Convert.ToInt32(str[1]);
List<int> list = null;
if ((N - M) <= 100000 && M >= 1 && M <= 1000000000 && N >= 1 && N <= 1000000000)
{
list = Enumerable.Range(M, (N - M + 1)).ToList();
int k = 2;
while (true)
{
if ((k * k) > N)
break;
List<int> tempList = new List<int>();
foreach (int item in list)
if (item != k && (item % k) == 0 && item != 1)
tempList.Add(item);
list = list.Except(tempList).ToList();
k++;
}
//list.Remove(1);
foreach (int item in list)
Console.WriteLine(item);
Console.WriteLine();
}
else
Console.WriteLine("Limit exceeded");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
}
}

All I can say is that looks like a lot of loops within loops you've got going on. Probably the main issue is just your general algorithm.
To test if a number is prime, it's sufficient to check whether it's evenly divisible by any number between 2 and its sqrt (rounded down).
But if you're checking many primes, you ought to leverage the fact that as you check higher and higher numbers you can start with only primes (I would store these in a simple List<int>). For example, say you've reached the number 27. You only need to check whether it's divisible by 2, 3, or 5 (the prime numbers you've already found less than sqrt(25) which is 5), not 4 (since 4 is divisible by 2—if it's divisible by 4, then it's divisible by 2), and not anything above that (if it's evenly divisible by anything above 5, the quotient will be below 5, and you would have already checked it).
Those are some general concepts that ought to help you optimize what looks upon first glance like a pretty inefficient algorithm.

There are three solutions to performance problems: benchmarks, benchmarks, benchmarks.
Use a profiler to benchmark your code. For C# I personally prefer ANTS Performance Profiler but there are also other options available.
I suggest you to update (or post another) your question with specific bottlenecks.

Your program is expected to output the numbers in 6 seconds(time-critical), so you should make full use of the memory in the 6 seconds to save time. For example, you can use multi-threading or parallel programming to generate numbers faster(more CPU/memory usages). Currently you are working in a regular way, which can't show off C#'s advantages(your code can be converted directly into C/Java/others with few changes). You need to do it in the C# way, otherwise why do you choose C#? Here is an example(non-tested, but I think it should be correct) which is much more in C# way.
int min = 2;
int max = 10000;
Enumerable.Range(min, max - min + 1)
.AsParallel()
.ForAll(g =>
{
bool prime = true;
for (int i = 2; i <= Math.Sqrt(g); i++)
{
if (g % i == 0)
{
prime = false;
break;
}
}
if (prime) Console.WriteLine(g);
});
EDIT: I just tested the code, primes less than 10000 are printed out in 0 seconds, measured by StopWatch.

Related

Find all possible multiplications numbers to a specified sum. C#

I need help with finding all possible unordered representations for a given natural number n(breakdowns) of n as a product of natural numbers (not necessarily different).
An integer n is entered from the keyboard.
Example: input: 50 output: 25 * 2 , 10 * 5 , 5 * 5 * 2
Hint: The algorithm by which you can perform the decomposition is analogous to the one that is
described in problem 3. Instead of devNum (n-k, cnt + 1) we will recursively call devNum (n / k, cnt + 1), when
this is not for every k, but only for those for which n% k == 0. The condition for continuing
the break (loop for) will be k & gt; 1, not k ≥ 1, i.e. the bottom of the recursion will be k == 1, not
k == 0 (the latter is easily explained: 0 and 1 are precisely the identities of the operations of addition and
multiplication).
This program I wrote may be close to what you're looking for. It would be helpful if you provided more information to the problem and any answers to prior questions (like question #3) and/or examples or clues provided by the homework on how the program is modeled. I can see there are strict constraints on how to write it, and not all of those exact boundaries are followed here. However, recursion is used on the same function with the same parameters, with similar arguments passed under certain conditionals. A list of lists is used to store the different sets of factors/divisors.
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
Console.WriteLine("Enter a positive integer: ");
int n;
while (!int.TryParse(Console.ReadLine(), out n))
{
Console.WriteLine("Please enter a whole number.");
}
List<List<int>> factors = FindFactors(n);
PrintFactors(factors);
}
public static List<List<int>> FindFactors(int n)
{
var res = new List<List<int>>();
if (n > 0) {
for (var i = n - 1; i >= 1; i--)
{
var temp = devNum(n, i);
foreach (var list in temp)
{
list.Reverse();
if (list.Count > 2 && list[list.Count - 1] == 1)
{
list.RemoveAt(list.Count - 1);
}
res.Add(list);
}
}
}
return res;
}
private static List<List<int>> devNum(int n, int k)
{
var beginWithFirst = new List<List<int>>();
if (n % k != 0 || (n > 1 && k == 1))
{
return beginWithFirst;
}
if (k == 1)
{
var end = new List<int>();
end.Add(k);
beginWithFirst.Add(end);
return beginWithFirst;
}
for (var i = n / k; i >= 1; i--)
{
var temp = devNum(n / k, i);
foreach (var list in temp.Where(list => list.Count > 0 && list[list.Count - 1] <= k))
{
list.Add(k);
beginWithFirst.Add(list);
}
}
return beginWithFirst;
}
public static void PrintFactors(List<List<int>> factors) {
int counter = 0;
foreach (List<int> lst in factors) {
counter++;
int[] arr = lst.ToArray();
if (counter != factors.Count) {
Console.Write("{0}", string.Join(" * ", arr) + ", ");
}
else {
Console.Write("{0}", string.Join(" * ", arr));
}
}
}
}
DotNet Fiddle

Print out the successful development of prime numbers from small to large

Given any natural number N> 1 (previously assigned). Print out the successful development of prime numbers from small to large.
Example:
9 --> 3 * 3
12 --> 2 * 2 * 3
My idea is find all GCD and add to list int, and write a function isPrimeNumber(int n), browse List< int > and check if isPrimeNumber().
But I can't solve problem print out the successful development of prime numbers from small to large
Here is what I tried
static void Main(string[] args)
{
Console.WriteLine("Enter n: ");
int n = Convert.ToInt32(Console.ReadLine());
List<int> arr = new List<int>();
for (int i = 1; i <= n; i++)
{
if (n % i == 0)
{
arr.Add(i);
}
}
/* I need Print out the successful development of prime numbers from small to large here */
}
static bool isPrimeNumber(int n)
{
if (n < 2)
{
return false;
}
for (int i = 2; i <= Math.Sqrt(n); i++)
{
if (n % i == 0)
{
return false;
}
}
return true;
}
As you posted your working solution for that, let me share a different implementation for that that is still simple to understand, but more efficient, because it only tests primes until it reaches the square root of n. After that, there will not be any other divisor, except the number n itself, if n is prime.
static IList<int> Factors(int num) {
var result = new List<int>();
// avoid scenarios like num=0, that would cause infinite loop
if (num <= 1) {
return result;
}
// testing with 2 outside the main loop, otherwise we would skip factor 3
// (2 * 2 > 3)
while (num % 2 == 0) {
result.Add(2);
num /= 2;
}
// only test primes until sqrt(num)
int i = 3;
while (i * i <= num) {
if (num % i == 0) {
result.Add(i);
num /= i;
} else {
i++;
}
}
// if not 1 here, num is prime
if (num > 1) {
result.Add(num);
}
return result;
}
I solved it
Here is code
static void lesson6()
{
Console.WriteLine("Enter n: ");
int n = Convert.ToInt32(Console.ReadLine());
int a = n;
List<int> arr = new List<int>();
for (int i = 2; i <= n; i++)
{
while (n % i == 0)
{
arr.Add(i);
n /= i;
}
}
Console.Write($"{a} = ");
int lastIndex = arr.Count - 1;
for (int i = 0; i < arr.Count; i++)
{
if (i == lastIndex)
{
Console.Write(arr[i]);
}
else
{
Console.Write(arr[i] + "*");
}
}
}
As pointed by derpirscher in the comment, there are several sources online with different approaches for integer factorization.
I recommend you to look for Trial Division algorithm, as it is the easier to understand, and is similar to your approach.
Based on the code you shared, there are some thing you should consider:
for (int i = 1; i <= n; i++)
{
if (n % i == 0)
{
arr.Add(i);
}
}
After finding that a prime is a divisor and appending to the list, you are going to the next number. However, a prime can figure many times in the factorization of a number. E.g: 12 -> { 2, 2, 3 }.
You need divide n by the prime and continue testing the until it is not a divisor anymore, then you can go test the next prime.
This way, your n is shrinking down each time you find a prime divisor, until it eventually become 1. Then you know you found all prime divisors.

Project Euler 1:Find the sum of all the multiples of 3 or 5 below 1000, works for 10 numbers but doesn't work for 1000 [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below 1000.
So I decided to try and solve some problems on Euler site to improve with programming. While trying to solve the first problem I wrote a quick code to count the sum and it worked for 10 numbers, but for 1000 it shows me the answer: 166833 which is wrong and I can't really find an issue here. If someone could give me a hint to improve my algorythm so it would work.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Multiplies_of_3_and_5
{
class Program
{
static void Main(string[] args)
{
int[] array = new int[7000];
for (int j = 0; j<array.Length ;j++)
{
array[j] = j + 1;
}
int n = 1;
int z = 1;
int numbers = 0;
for (int i = 0; i<999; i++)
{
if (array[i] == 3 * n )
{
n++;
numbers += array[i];
}
else if (array[i] == 5 * z)
{
z++;
numbers += array[i];
}
}
Console.WriteLine(string.Join(" ", numbers));
Console.ReadLine();
}
}
}
Idea count 3s, 5s and deduct 15s as they are in both but only need counting once.
int maxNum = 999;
int num3s = maxNum/3; // rounded down 333
int num5s = maxNum/5; // rounded down 199
int num15s = maxNum/15; // rounded down 66
Knowing how many still isn't going to tell us the sum. Pythagoras to the rescue.
sum3s = 3+6+9+12+15 (=45)
sum5s = 5+10+15 (=30)
sum15s = 15 (=15)
average = (max+min)/2
Either there is an odd number of 3's, 5's or 15's and you get an even average. Or there is an even number in which case /2 and the even cancel each other.
So we get
sumXs = (min+max)*numXs
In the above case we get
sum3s = (3+15)/2*5 = 45
sum5s = (5+15)/2*3 = 30
sum15s = (15+15)/2*1 = 15
int sum = sum3s+sum5s-sum15s = 60;
Another example 11
sum = (3+9)/2*3 + (5+10)/2*2 - 0 = 33
And finally sum of 3s and 5s up to 999
sum = (3+999)/2*333 + (5+995)/2*199 - (15+990)/2*66
= 501*333 + 500*199 - (1005)*66/2
= 501*333 + 500*199 - 1005*33
= 166833 + 99500 - 33165
= 233168
Which is also the result of the programs.
You should read up on the modulo operator (%).
static void main(String[] args)
{
int sum = 0;
for(int i=1; i< 1000; i++){
if (i % 3 == 0 || i % 5 == 0){
sum += i;
}
}
Console.WriteLine(sum);
}
To give an explanation, the modulo operator gives the remainder when performing integer division on a value.
For example, 6 % 3 == 0 (3 evenly divides 6), 7 % 3 == 1 (7 divided by 3 leaves remainder 1).
So to sum all of the multiples of 3 and 5, just check if the value divides evenly by 3 or 5 (the if statement), and if so, add it to the running sum.
Note that your algorithm is going to screw up when you get to numbers that are multiple of 3 AND 5. You never add to z in that case. You also need to change it to be <= 999, not <999 (you will never add 999 in your code, which divides by 3).
To sum things up:
Use your loop variable directly, no need to pre-populate another
array or have separate values keeping track of what multiple you're
at.
Modulo is super useful.
When reaching 15, n will increase but z won't. Therefore the second branch ("is divideable by 5") won't trigger anymore.
You can either use flags for both and then use those flags to increase numbers, n and z or use modulo as suggested.
Enumerable.Range(1, 999).Sum(x => x % 3 == 0 || x % 5 == 0 ? x : 0);
After listening to tips from You I remade my code and it works just fine. But it is surely a pain to do it this way, so I suggest using (%) for that. Anyway I will post my code here as well. Thanks for help again!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Multiplies_of_3_and_5
{
class Program
{
static void Main(string[] args)
{
int[] array = new int[7000];
for (int j = 0; j < array.Length; j++)
{
array[j] = j + 1;
}
int n = 1;
int z = 1;
int numbers = 0;
for (int i = 0; i < 999; i++)
{
if (array[i] == 3*n && array[i] == 5*z)
{
n++;
}
if (array[i] == 3 * n)
{
n++;
numbers += array[i];
}
if (array[i] == 5 * z)
{
z++;
numbers += array[i];
}
}
Console.WriteLine(string.Join(" ", numbers));
Console.ReadLine();
}
}
}

C# perfect numbers exercise

can you help me with the following exercise pls? (it's not homework, just an exercise in the book I'm using.)
"An integer is said to be a perfect number if its factors, including one (but not the number itself), sum to the number. For example, 6 is a perfect number, because 6 = 1 + 2 + 3. Write method Perfect that determines whether parameter value is a perfect number. Use this method in an app that determines and displays all the perfect numbers between 2 and 1000. Display the factors of each perfect number to confirm that the number is indeed perfect."
so here's what i got so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Perfect_Numbers2
{
class Program
{
static bool IsItPerfect(int value)
{
int x = 0;
int counter = 0;
bool IsPerfect = false;
List<int> myList = new List<int>();
for (int i = value; i <= value; i++)
{
for (int j = 1; j < value; j++)
{
// if the remainder of i divided by j is zero, then j is a factor of i
if (i%j == 0) {
myList[counter] = j; //add j to the list
counter++;
}
for (int k = 0; k < counter; k++)
{
// add all the numbers in the list together, then
x = myList[k] + myList[k + 1];
}
// test if the sum of the factors equals the number itself (in which case it is a perfect number)
if (x == i) {
IsPerfect = true;
}
}
Console.WriteLine(i);
}
return IsPerfect;
}
static void Main(string[] args)
{
bool IsItAPerfectNum = false;
for (int i = 2; i < 1001; i++)
{
IsItAPerfectNum = IsItPerfect(i);
}
}
}
}
how would you do it? is my code fixable? how would you fix it? thanks!
im getting an error at line myList[counter] = j; (index was out of range) and besides it's not displaying the perfect numbers like it's supposed to....
EDIT = I made some changes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Perfect_Numbers2
{
class Program
{
static bool IsItPerfect(int value)
{
int x = 0;
int counter = 0;
bool IsPerfect = false;
List<int> myList = new List<int>();
for (int i = value; i <= value; i++)
{
for (int j = 1; j < i; j++)
{
if (i%j == 0) // if the remainder of i divided by j is zero, then j is a factor of i
{
myList.Add(j); //add j to the list
}
x = myList.Sum();
if (x == i) // test if the sum of the factors equals the number itself (in which case it is a perfect number)
{
IsPerfect = true;
}
}
Console.WriteLine(i);
}
return IsPerfect;
}
static void Main(string[] args)
{
bool IsItAPerfectNum = false;
for (int i = 2; i < 1001; i++)
{
IsItAPerfectNum = IsItPerfect(i);
Console.WriteLine(IsItAPerfectNum);
Console.ReadKey(true);
}
}
}
}
now i can cycle through all the numbers until 1000 and it displays if it's perfect or not (true or false) [which isn't what the exercise called for, but it's a step in the right direction (the exercise says that it should display only the perfect numbers)].
In any case, what's strange is that it says true at number 24, which isn't a perfect number.... http://en.wikipedia.org/wiki/Perfect_numbers#Examples
why is 24 different?
thanks very much
can you help me with the following exercise please?
Yes. Rather than showing you where your error is, I'll teach you how to find your error. Even better, the same technique will lower the chances of you causing the error in the first place.
The key here is to break the problem down into small parts where each small part can be tested independently. You have already started to do this! You have two methods: Main and IsItPerfect. You should have at least three more methods. The methods you should have are:
IsDivisor -- takes two integers, returns true if the first divides the second.
GetAllDivisors -- takes an integer, returns a list of all the divisors
Sum -- takes a list of integers, returns the sum
Your method IsPerfect should be calling GetAllDivisors and Sum and comparing the sum to the original number, and that's all it should be doing. Your method GetAllDivisors should be calling IsDivisor, and so on.
You can't find the bug easily because your method is doing too much. If you're not getting the correct result out and you have four methods instead of one then you can test each method independently to make sure that it works, or fix it if it does not.
Your first for loop will be executed exactly once.
for (int i = value; i <= value; i++)
For example for value = 6
for (int i = 6; i <= 6; i++)
Some help with the 24 issue you are having: 24 is returning true as you are actually checking if it is perfect on every additional factor. So 24 gets flipped to true here:
Factors of 24 | Total so far
1 1
2 3
3 6
4 10
6 16
8 24 <-- returns true
12 36 <-- should be false, but flag is never reset
I have just now completed the same exercise which is from a really great book called visual c# 2012 by Mr Deitel.
The way i started to tackle is, i started off with figuring out how to work out the factorials of numbers and then slowly kept building on from there.
Since you are following the same book, i would suggest you not to use things that are not covered up to that chapters exercise, like list collections which you have used, As this will make the exercise unnecessarily difficult. and negates the learning methodology set out by of the author.
here is my code which i hope can help you in some way.
class Program
{
static int factorTotal = 1;
static void Main(string[] args)
{
int count = 1;
while (count <= 10000)
{
bool isPerfect = IsPerfectNumber(count);
if (isPerfect && (factorTotal >1))
{
Console.WriteLine("Is Perfect: {0}", factorTotal);
}
factorTotal = 1;
count++;
}
} // end main
static bool IsPerfectNumber(int n)
{
int temp;
int counter = 2;
bool IsPerfect = false;
while (counter <= (n - 1))
{
temp = n % counter;
if (temp == 0) // if true than factor found
{
factorTotal = factorTotal + counter;
}
counter++;
}
if ((factorTotal) == n)
IsPerfect = true;
else
IsPerfect = false;
return IsPerfect;
}
}//end class
under the Main method of you console application copy and paste below code.
I explained few things at the end of the code...
=====================================================================
{
Console.WriteLine("perfect numbers/n");
Console.Write("Enter upper limit: ");
int iUpperLimit = int.Parse(Console.ReadLine());
string sNumbers = "";
List<int> lstFactor = new List<int>();
for(int i = 1;i<=iUpperLimit;i++)
{
for(int k = 1;k<i;k++)
{
if (i % k == 0)
{
lstFactor.Add(k); //this collect all factors
}
if (k == i-1)
{
if (lstFactor.Sum() == i) //explain1
{
sNumbers += " " + i;
lstFactor.Clear(); //explain2
break;
}
else
{
lstFactor.Clear(); //explain2
}
}
}
}
Console.WriteLine("\nperfect numbers are: " + sNumbers);
Console.ReadKey();
}
}
=======================================================================
note that i is a number that we test and k is its factors.
explain1 => we add all factors collected and check if they are equal to i (we simply check if i is perfect number)
explain2 => we have to clear our list before we can check if the next number i is a perfect number or not so that factors of the previous number does not interfere with factors of the current number.
int start=1;
int end=50;
for(int a=end ; a > start ;a--)
{
int b=1;
int c=0;
bool x=false;
for(int i=1 ; i < a ;i++)
{
b=a/i;
if(b*i==a)
{
c+=i;
}
if(c==a & i==a/2)
{
x=true;
}
}
if(x==true)
Console.Write("{0} is : {1}",a,x);
}

C#, finding the largest prime factor of a number

I am new at programming and I am practicing my C# programming skills. My application is meant to find the largest prime factor of a number entered by the user. But my application is not returning the right answer and I dont really know where the problem is. Can you please help me?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Calcular máximo factor primo de n. De 60 es 5.");
Console.Write("Escriba un numero: ");
long num = Convert.ToInt64(Console.ReadLine());
long mfp = maxfactor(num);
Console.WriteLine("El maximo factor primo es: " + num);
Console.Read();
}
static private long maxfactor (long n)
{
long m=1 ;
bool en= false;
for (long k = n / 2; !en && k > 1; k--)
{
if (n % k == 0 && primo(k))
{
m = k;
en = true;
}
}
return m;
}
static private bool primo(long x)
{
bool sp = true;
for (long i = 2; i <= x / 2; i++)
{
if (x % i == 0)
sp = false;
}
return sp;
}
}
}
It will be much faster to remove the small factors until the residue is prime.
static private long maxfactor (long n)
{
long k = 2;
while (k * k <= n)
{
if (n % k == 0)
{
n /= k;
}
else
{
++k;
}
}
return n;
}
For example, if n = 784, this does 9 modulo operations instead of several hundred. Counting down even with the sqrt limit still would do 21 modulo ops just in maxfactor, and another dozen in primo.
New more optimized version here
Console.WriteLine("El maximo factor primo es: " + mfp);
instead of
Console.WriteLine("El maximo factor primo es: " + num);
you have condition (!en) that makes it iterate only until first prime factor. Also you can reduce bounds from n/2 to sqrt(n)+1
Catalin DICU already answered your question, but you've got some non-idiomatic constructs in your code that you should probably look at refactoring. For example, in your maxfactor method, you don't need the "en" condition, just return the value as soon as you've found it:
static private long maxfactor (long n)
{
for (long k = n / 2; k > 1; k--)
{
if (n % k == 0 && primo(k))
{
return k;
}
}
// no factors found
return 1;
}
Similarly for your primo method, you can just return false as soon as you find a factor.
here's a f# version for this:
let lpf n =
let rec loop n = function
|k when k*k >= n -> n
|k when n % k = 0I -> loop (n/k) k
|k -> loop n (k+1I)
loop n 2I
This runs for less than three seconds.
public static void Main()
{
int prime=1;
long n=600851475143;
for (long i=2;i<=n;i++)
{
while (n%i==0)
n=n/i;
prime++;
}
Console.WriteLine(prime);
Console.WriteLine("Hello World!");
Console.ReadKey();
}

Categories

Resources