Detection a two different math cases using c# - c#

I have this code that should run "Amount" times. The code has to do a math equation called
collatz conjecture, how it works is you get a number, if its odd you have to * by 3 and than add 1 but if its even you have to divide it by 2, this should go on until the number hits one, if the number does it one the variable Ver should be added but one otherwise this should get in a never ending loop, The problem is I don't know how to detect that loop. The code bellow is the whole thing without the loop detection and when I run it 1 million times it worked fine expect 432 numbers specifically that should not get in that loop.
The problem is you never know if the math equation is still happening or is it a special case that will never hit the number 1.
using System.Collections.Generic;
using System;
int Amount = 1000000;
int Ver = 0;
Amount++;
for (int i = 1; i < Amount; i++)
{
int i2 = i;
while (i2 > 1)
{
if (i2 % 2 == 0) {
int i3 = i2 / 2;
i2 = i3;
}
else
{
i2 = (i2 * 3) + 1;
}
}
if (i2 == 1 || i2==4 || i2==2)
Ver++;
}
Amount--;
Console.WriteLine(Ver + " of "+ Amount + " numbers were verified.");
A good idea would be if the program was stuck on number for too long (More than 2 or 3 minuets) to Maybe ask in the console to see if the program should continue on a number or should it skip that number. I have tried putting on timer each time it gets to a new number but it will slow the program by almost 3 or 4 times. Does anyone know a faster way to do that?

This solution does not pretend to be academic.
Due to link you provided you must use ulong (UInt64) at least instead of int (Int32)
You can use TPL DataFlow with CancellationToken:
using System.Collections.Concurrent;
using System.Threading.Tasks.Dataflow;
const ulong start = 20_000_001;
const ulong amount = 10_000_000;
const ulong maxIterations = 1000_0000;
ulong verified = 0;
ConcurrentBag<ulong> canceledNumbers = new ConcurrentBag<ulong>();
ConcurrentBag<ulong> overflowNumbers = new ConcurrentBag<ulong>();
var actionBlock = new ActionBlock<ulong>(CollatzAction,
new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = Environment.ProcessorCount * 2, // Remove 2 if you don't have hyperthreading
BoundedCapacity = Environment.ProcessorCount * 4, // Back pressure to avoid the memory overhead
});
for (ulong i = start; i < start + amount; i++)
{
await actionBlock.SendAsync(i).ConfigureAwait(false);
}
actionBlock.Complete();
await actionBlock.Completion.ConfigureAwait(false);
Console.WriteLine($"{verified} of {amount} numbers were verified, {canceledNumbers.Count} were canceled.");
if (!canceledNumbers.IsEmpty)
{
Console.WriteLine($"Canceled numbers are: {string.Join(", ", canceledNumbers)}");
}
if (!overflowNumbers.IsEmpty)
{
Console.WriteLine($"Overflow numbers are: {string.Join(", ", overflowNumbers)}");
}
void CollatzAction(ulong i)
{
try
{
var (oneIsReached, isCanceled) = Collatz(i);
if (oneIsReached)
{
Interlocked.Increment(ref verified);
}
else if (isCanceled)
{
canceledNumbers.Add(i);
}
}
catch (OverflowException)
{
overflowNumbers.Add(i);
}
}
(bool oneIsReached, bool isCanceled) Collatz(ulong i)
{
ulong iteration = 1;
while (i > 1 && iteration <= maxIterations)
{
i = (i & 1) == 0 // the same as i % 2 == 0 but faster
? i / 2
: checked(i * 3 + 1);
iteration++;
}
return (i == 1, iteration > maxIterations);
}
You can try to replace ulong with BigInteger to avoid overflows, but it's much slower:
using System.Collections.Concurrent;
using System.Numerics;
using System.Threading.Tasks.Dataflow;
BigInteger start = 100_000_001;
const ulong amount = 10_000_000;
const ulong maxIterations = 1000_0000;
ulong verified = 0;
ConcurrentBag<BigInteger> canceledNumbers = new ConcurrentBag<BigInteger>();
var actionBlock = new ActionBlock<BigInteger>(CollatzAction,
new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = Environment.ProcessorCount * 2, // Remove 2 if you don't have hyperthreading
BoundedCapacity = Environment.ProcessorCount * 4, // Back pressure to avoid the memory overhead
});
for (BigInteger i = start; i < start + amount; i++)
{
await actionBlock.SendAsync(i).ConfigureAwait(false);
}
actionBlock.Complete();
await actionBlock.Completion.ConfigureAwait(false);
Console.WriteLine($"{verified} of {amount} numbers were verified, {canceledNumbers.Count} were canceled.");
if (!canceledNumbers.IsEmpty)
{
Console.WriteLine($"Canceled numbers are: {string.Join(", ", canceledNumbers)}");
}
void CollatzAction(BigInteger i)
{
var (oneIsReached, isCanceled) = Collatz(i);
if (oneIsReached)
{
Interlocked.Increment(ref verified);
}
else if (isCanceled)
{
canceledNumbers.Add(i);
}
}
(bool oneIsReached, bool isCanceled) Collatz(BigInteger i)
{
ulong iteration = 1;
while (i > 1 && iteration <= maxIterations)
{
i = (i & 1) == 0 // the same as i % 2 == 0 but faster
? i / 2
: i * 3 + 1;
iteration++;
}
return (i == 1, iteration > maxIterations);
}

Related

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.

Find the 10001st prime

I took a look at the following question from project euler:
By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.
What is the 10 001st prime number?
I tried to take the square root of the number and than find all the prime numbers below the square root of the number and then divide the number by all the square roots and see if there is 0 left each time. If the number is not divisible by all the primes under its square root its a prime number. I did this to lower the itterations the programm has to make. Here is what I have now, I am not sure why it isn't working. Anybody knows what i did wrong?
List<int> primeNumbers = new List<int>();
bool prime = true;
bool MainPrime = true;
int check = 1;
for (long i = 3; i < long.MaxValue; i++)
{
if ((i % 2) != 0)
{
int root = Convert.ToInt32(Math.Sqrt(i));
for (int j = 1; j < root; j++)
{
for (int k = 2; k < j; k++)
{
if ((j% k) == 0)
{
prime = false;
}
}
if (prime)
{
primeNumbers.Add(j);
}
prime = true;
}
}
foreach (var item in primeNumbers)
{
if ((i%item) == 0)
{
MainPrime = false;
}
}
primeNumbers.Clear();
if (MainPrime)
{
check++;
}
if (check == 10001)
{
Console.WriteLine(i);
break;
}
}
Console.ReadKey();
Several points:
When finding possible prime divisors, you need to check all numbers up to the square root included, so your condition j < root is incorrect.
You don't have to recalculate the primes again for every number. Keep the list as you go and add new primes to it.
As soon as you find a divisor, you can break out of the foreach loop.
Improved code:
List<long> primeNumbers = new List<long>() { 2 };
for (long i = 3; i < long.MaxValue; i += 2)
{
if(!primeNumbers.Any(p => (i % p) == 0))
{
primeNumbers.Add(i);
if (primeNumbers.Count == 10001)
{
Console.WriteLine(i);
break;
}
}
}
Gives 104743 as the 10001st prime.
What we can do is we can use SieveOfEratosthenes to make an bool array in which all the prime numbers value are set to be true than after that;
1.As we found any prime number increment the count with 1;
2.And as count get equal to 10001 we print its value and break through the loop.
Have a Look at code in C++ (I recommend you to learn SieveOfEratosthenes first)
#include <bits/stdc++.h>
using namespace std;
void SieveOfEratosthenes(long long unsigned n)
{
bool prime[n];
memset(prime, true, sizeof(prime)); //This is SieveOfEratosthenes
for (long long p = 2; p * p <= n; p++)
{
if (prime[p] == true)
{
for (long long i = p * p; i <= n; i += p)
prime[i] = false;
}
}
long long count=0; //initializing count as 0;
for (long long p = 2; p <= n; p++) //running the loop form 2 to n
{
if (prime[p]) //we have bool array in which all prime number set to true using sieve
count++; //increment the count because we found a prime number
if(count==10001) // and as count reaches to 10001 we found our number
{
cout<<p;break;} // print the answer and also break form the loop
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
long long unsigned n=999999;
SieveOfEratosthenes(n); //pass the value of n in sieve function
return 0;
}
Try this one out using python
sp=2
cnt = 1
while cnt <= 10001:
primeflag = 0
for j in range(2,sp):
if(sp%j == 0):
primeflag = 1
break;
if(primeflag == 1):
pass
else:
print(cnt ,sp)
cnt = cnt +1
sp =sp+1
#which Gives
#10001 104743

Parallel factorial with multiple threads

I'm trying to make a function that calculates factorial of a number in parallel, just for testing purposes.
Let's say I have 4 cores on my cpu, so I will split the "problem" in 4 chunks.
Saying that, I made this:
public class FactorialPTest
{
public static object _locker = new object();
public static long Factorial(int x)
{
long result = 1;
int right = 0;
int nr = x;
bool done = false;
for (int i = 0; i < nr; i += (nr / 4))
{
int step = i;
new Thread(new ThreadStart(() =>
{
right = (step + nr / 4) > nr ? nr : (step + nr / 4);
long chunkResult = ChunkFactorial(step + 1, right);
lock (_locker)
{
result *= chunkResult;
if (right == nr)
done = true;
}
})).Start();
}
while(!done)
{
Thread.Sleep(10);
}
return result;
}
public static long ChunkFactorial(int left, int right)
{
//Console.WriteLine("left: {0} ; right: {1}", left, right);
Console.WriteLine("ChunkFactorial Thread ID :" + Thread.CurrentThread.ManagedThreadId);
if (left == right)
return left == 0 ? 1 : left;
else return right * ChunkFactorial(left, right - 1);
}
public static void main()
{
Console.WriteLine(Factorial(15));
}
}
Sometimes is working, sometimes it gives me intermediary results and sometimes a deadlock happens.
Why is this happening? Shouldn't Thread.Sleep(10) pause the main thread until I get the final result ?
I'd suggest looking into the Task Parallel Library. Among other things it will abstract away a lot of the low concerns relating to multi-threading.
You can represent each chunk of work with a task, add to a collection and then wait for them all to finish:
public static long Factorial(int x)
{
long result = 1;
int right = 0;
int nr = x;
bool done = false;
var tasks = new List<Task>();
for (int i = 0; i < nr; i += (nr / 4))
{
int step = i;
tasks.Add(Task.Run(() =>
{
right = (step + nr / 4) > nr ? nr : (step + nr / 4);
long chunkResult = ChunkFactorial(step + 1, right);
lock (_locker)
{
result *= chunkResult;
}
}));
}
Task.WaitAll(tasks.ToArray());
return result;
}
In your original code the last chunk could conceivably complete it's work first and right would equal nr even though the other chunks hadn't been calculated. Also, right was getting shared between all the threads so this could also lead to some unpredictable results, i.e, all threads are trying to use this variable to hold different values at the same time.
Generally you should try to avoid sharing state between threads if possible. The code above could be improved by having each task return it's result and then use these results to calculate the final one:
public static long Factorial(int x)
{
int nr = x;
var tasks = new List<Task<long>>();
for (int i = 0; i < nr; i += (nr / 4))
{
int step = i;
tasks.Add(Task.Run(() =>
{
int right = (step + nr / 4) > nr ? nr : (step + nr / 4);
return ChunkFactorial(step + 1, right);
}));
}
Task.WaitAll(tasks.ToArray());
return tasks.Select(t => t.Result).Aggregate(((i, next) => i * next));
}
You could use one of the Parallel.For overloads with aggregation, it will handle parallelism, partitioning of the workload and aggregation of the results for you. For long type of result, you can only do factorial of 21, if I am not mistaken. It also makes sense to add checked {...} to catch overflows. The code could looks like:
public long CalculateFactorial(long value)
{
var result = 1L;
var syncRoot = new object();
checked
{
Parallel.For(
// always 1
1L,
// target value
value,
// if need more control, add { MaxDegreeOfParallelism = 4}
new ParallelOptions(),
// thread local result init
() => 1L,
// next value
(i, state, localState) => localState * i,
// aggregate local thread results
localState =>
{
lock (syncRoot)
{
result *= localState;
}
}
);
}
return result;
}
Hope this helps.

An algorithm for a number divisible to n

At first user gives a number (n) to program, for example 5.
the program must find the smallest number that can be divided to n (5).
and this number can only consist of digits 0 and 9 not any other digits.
for example if user gives 5 to program.
numbers that can be divided to 5 are:
5, 10, 15, 20, 25, 30, ..., 85, 90, 95, ...
but 90 here is the smallest number that can be divided to 5 and also consist of digits (0 , 9). so answer for 5 must be 90.
and answer for 9 is 9, because it can be divided to 9 and consist of digit (9).
my code
string a = txtNumber.Text;
Int64 x = Convert.ToInt64(a);
Int64 i ,j=1,y=x;
bool t = false;
for (i = x + 1; t == false; i++)
{
if (i % 9 == 0 && i % 10 == 0 && i % x == 0)
{
j = i;
for (; (i /= 10) != 0; )
{
i /= 10;
if (i == 0)
t = true;
continue;
}
}
}
lblAnswer.Text = Convert.ToString(j);
If you're happy to go purely functional then this works:
Func<IEnumerable<long>> generate = () =>
{
Func<long, IEnumerable<long>> extend =
x => new [] { x * 10, x * 10 + 9 };
Func<IEnumerable<long>, IEnumerable<long>> generate2 = null;
generate2 = ns =>
{
var clean = ns.Where(n => n > 0).ToArray();
return clean.Any()
? clean.Concat(generate2(clean.SelectMany(extend)))
: Enumerable.Empty<long>();
};
return generate2(new[] { 9L, });
};
Func<long, long?> f = n =>
generate()
.Where(x => x % n == 0L)
.Cast<long?>()
.FirstOrDefault();
So rather than iterate through all possible values and test for 0 & 9 and divisibility, this just generates only numbers with 0 & 9 and then only tests for visibility. It is much faster this way.
I can call it like this:
var result = f(5L); // 90L
result = f(23L); //990909L
result = f(123L); //99999L
result = f(12321L); //90900999009L
result = f(123212L); //99909990090000900L
result = f(117238L); //990990990099990990L
result = f(1172438L); //null == No answer
These results are super fast. f(117238L) returns a result on my computer in 138ms.
You can try this way :
string a = txtNumber.Text;
Int64 x = Convert.ToInt64(a);
int counter;
for (counter = 1; !isValid(x * counter); counter++)
{
}
lblAnswer.Text = Convert.ToString(counter*x);
code above works by searching multiple of x incrementally until result that satisfy criteria : "consist of only 0 and or 9 digits" found. By searching only multiple of x, it is guaranteed to be divisible by x. So the rest is checking validity of result candidate, in this case using following isValid() function :
private static bool isValid(int number)
{
var lastDigit = number%10;
//last digit is invalid, return false
if (lastDigit != 0 & lastDigit != 9) return false;
//last digit is valid, but there is other digit(s)
if(number/10 >= 1)
{
//check validity of digit(s) before the last
return isValid(number/10);
}
//last digit is valid, and there is no other digit. return true
return true;
}
About strange empty for loop in snippet above, it is just syntactic sugar, to make the code a bit shorter. It is equal to following while loop :
counter = 1;
while(!isValid(input*counter))
{
counter++;
}
Use this simple code
int inputNumber = 5/*Or every other number, you can get this number from input.*/;
int result=1;
for (int i = 1; !IsOk(result,inputNumber); i++)
{
result = i*inputNumber;
}
Print(result);
IsOk method is here:
bool IsOk(int result, int inputNumber)
{
if(result%inputNumber!=0)
return false;
if(result.ToString().Replace("9",string.Empty).Replace("0",string.Empty).Length!=0)
return false;
return true;
}
My first solution has very bad performance, because of converting a number to string and looking for characters '9' and '0'.
New solution:
My new solution has very good performance and is a technical approach since of using Breadth-first search(BFS).
Algorithm of this solution:
For every input number, test 9, if it is answer print it, else add 2 child numbers (90 & 99) to queue, and continue till finding answer.
int inputNumber = 5;/*Or every other number, you can get this number from input.*/
long result;
var q = new Queue<long>();
q.Enqueue(9);
while (true)
{
result = q.Dequeue();
if (result%inputNumber == 0)
{
Print(result);
break;
}
q.Enqueue(result*10);
q.Enqueue(result*10 + 9);
}
Trace of number creation:
9
90,99
900,909,990,999
9000,9009,9090,9099,9900,9909,9990,9999
.
.
.
I wrote this code for console, and i used goto command however it is not prefered but i could not write it with only for.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace main
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter your number");
Int64 x = Convert.ToInt64(Console.ReadLine());
Int64 y, j, i, k, z = x;
x = x + 5;
loop:
x++;
for (i = 0, y = x; y != 0; i++)
y /= 10;
for (j = x, k = i; k != 0; j /= 10, k--)
{
if (j % 10 != 9)
if (j % 10 != 0)
goto loop;
}
if (x % z != 0)
goto loop;
Console.WriteLine("answer:{0}",x);
Console.ReadKey();
}
}
}

Prime Number Formula

I am trying to write a prime number function in C# and I am wondering if the follow code will work. It "appears" to work with the first 50 numbers or so. I just want to make sure it will work no matter how big the number is:
static bool IsPrime(int number)
{
if ((number == 2) || (number == 3) || (number == 5) || (number == 7) || (number == 9))
return true;
if ((number % 2 != 0) && (number % 3 != 0) && (number % 5 != 0) &&
(number % 7 != 0) && (number % 9 != 0) && (number % 4 != 0) &&
(number % 6 != 0))
return true;
return false;
}
No it won't work! Try 121 = 11 * 11 for example which obviously isn't a prime.
For any number given to your function, that is a product of the prime numbers X1, X2, ..., Xn(where n >= 2) with all of them being greater or equal to 11, your function will return true. (And also, as already said, 9 isn't a prime).
From wikipedia you can see that:
In mathematics, a prime number (or a prime) is a natural number that has exactly two distinct natural number divisors: 1 and itself.
so a very simple and naive algorithm on checking whether a number is prime could be:
public bool CalcIsPrime(int number) {
if (number == 1) return false;
if (number == 2) return true;
if (number % 2 == 0) return false; // Even number
for (int i = 2; i < number; i++) { // Advance from two to include correct calculation for '4'
if (number % i == 0) return false;
}
return true;
}
For better algorithms check here: Primality Test
If you want to check your code, do inlcude a test, here's a test case written in xunit.
[Theory]
[MemberData(nameof(PrimeNumberTestData))]
public void CalcIsPrimeTest(int number, bool expected) {
Assert.Equal(expected, CalcIsPrime(number));
}
public static IEnumerable<object[]> PrimeNumberTestData() {
yield return new object[] { 0, false };
yield return new object[] { 1, false };
yield return new object[] { 2, true };
yield return new object[] { 3, true };
yield return new object[] { 4, false };
yield return new object[] { 5, true };
yield return new object[] { 6, false };
yield return new object[] { 7, true };
yield return new object[] { 8, false };
yield return new object[] { 9, false };
yield return new object[] { 10, false };
yield return new object[] { 11, true };
yield return new object[] { 23, true };
yield return new object[] { 31, true };
yield return new object[] { 571, true };
yield return new object[] { 853, true };
yield return new object[] { 854, false };
yield return new object[] { 997, true };
yield return new object[] { 999, false };
}
It had to be done...
public static bool IsPrime(this int number)
{
return (Enumerable.Range(1,number).Where(x => number % x == 0).Count() == 2);
}
This approach definitely won't work, unless your if statement explicitly enumerates all the prime numbers between 0 and sqrt(INT_MAX) (or the C# equivalent).
To properly check for primality, you basically need to attempt to divide your number by every prime number less than its square root. The Sieve of Eratosthenes algorithm is your best bet.
You are apparently writing from a contrafactual dimension where 9 is a prime number, so I guess that our answers might not work for you. Two things though:
Prime number generating functions are a non-trivial but exiting matter, the Wikipedia page is a good starter (http://en.wikipedia.org/wiki/Formula_for_primes)
from (number%2!=0) it follows (number%4!=0). If you can't divide by 10, then you can't divide by 100 either.
Primality testing is the way to go, but in case you want a quick and dirty hack, here's something.
If it's not working fast enough, you can build a class around it and store the PrimeNumbers collection from call to call, rather than repopulating it for each call.
public bool IsPrime(int val)
{
Collection<int> PrimeNumbers = new Collection<int>();
int CheckNumber = 5;
bool divisible = true;
PrimeNumbers.Add(2);
PrimeNumbers.Add(3);
// Populating the Prime Number Collection
while (CheckNumber < val)
{
foreach (int i in PrimeNumbers)
{
if (CheckNumber % i == 0)
{
divisible = false;
break;
}
if (i * i > CheckNumber) { break; }
}
if (divisible == true) { PrimeNumbers.Add(CheckNumber); }
else { divisible = true; }
CheckNumber += 2;
}
foreach (int i in PrimeNumbers)
{
if (CheckNumber % i == 0)
{
divisible = false;
break;
}
if (i * i > CheckNumber) { break; }
}
if (divisible == true) { PrimeNumbers.Add(CheckNumber); }
else { divisible = true; }
// Use the Prime Number Collection to determine if val is prime
foreach (int i in PrimeNumbers)
{
if (val % i == 0) { return false; }
if (i * i > val) { return true; }
}
// Shouldn't ever get here, but needed to build properly.
return true;
}
There are some basic rules you can follow to check if a number is prime
Even numbers are out. If x % 2 = 0, then it is not prime
All non-prime numbers have prime factors. Therefore, you only need test a number against primes to see if it factors
The highest possible factor any number has is it's square root. You only need to check if values <= sqrt(number_to_check) are even divisible.
Using that set of logic, the following formula calculates 1,000,000 Primes Generated in: 134.4164416 secs in C# in a single thread.
public IEnumerable<long> GetPrimes(int numberPrimes)
{
List<long> primes = new List<long> { 1, 2, 3 };
long startTest = 3;
while (primes.Count() < numberPrimes)
{
startTest += 2;
bool prime = true;
for (int pos = 2; pos < primes.Count() && primes[pos] <= Math.Sqrt(startTest); pos++)
{
if (startTest % primes[pos] == 0)
{
prime = false;
}
}
if (prime)
primes.Add(startTest);
}
return primes;
}
Bear in mind, there is lots of room for optimization in the algorithm. For example, the algorithm could be parallelized. If you have a prime number (let's say 51), you can test all the numbers up to it's square (2601) for primeness in seperate threads as all it's possible prime factors are stored in the list.
static List<long> PrimeNumbers = new List<long>();
static void Main(string[] args)
{
PrimeNumbers.Add(2);
PrimeNumbers.Add(3);
PrimeNumbers.Add(5);
PrimeNumbers.Add(7);
for (long i = 11; i < 10000000; i += 2)
{
if (i % 5 != 0)
if (IsPrime(i))
PrimeNumbers.Add(i);
}
}
static bool IsPrime(long number)
{
foreach (long i in PrimeNumbers)
{
if (i <= Math.Sqrt(number))
{
if (number % i == 0)
return false;
}
else
break;
}
return true;
}
this is a simple one
only odd numbers are prime....so
static bool IsPrime(int number)
{
int i;
if(number==2)
return true; //if number is 2 then it will return prime
for(i=3,i<number/2;i=i+2) //i<number/2 since a number cannot be
{ //divided by more then its half
if(number%i==0) //if number is divisible by i, then its not a prime
return false;
}
return true; //the code will only reach here if control
} //is not returned false in the for loop
This is a simple code for find prime number depend on your input.
static void Main(string[] args)
{
String input = Console.ReadLine();
long num = Convert.ToInt32(input);
long a, b, c;
c = 2;
for(long i=3; i<=num; i++){
b = 0;
for (long j = 2; j < i ; j++) {
a = i % j;
if (a != 0) {
b = b+1;
}
else {
break;
}
}
if(b == i-2){
Console.WriteLine("{0}",i);
}
}
Console.ReadLine();
}
ExchangeCore Forums have a good bit of code that will pretty much let you generate any ulong number for primes. But basically here's the gist:
int primesToFind = 1000;
int[] primes = new int[primesToFind];
int primesFound = 1;
primes[0] = 2;
for(int i = 3; i < int.MaxValue() && primesFound < primesToFind; i++)
{
bool isPrime = true;
double sqrt = Math.sqrt(i);
for(int j = 0; j<primesFound && primes[j] <= sqrt; j++)
{
if(i%primes[j] == 0)
{
isPrime = false;
break;
}
}
if(isPrime)
primes[primesFound++] = i;
}
Once this code has finished running your primes will all be found in the primes array variable.
https://www.khanacademy.org/computing/computer-science/cryptography/comp-number-theory/a/trial-division
public static bool isPrime(int number)
{
for (int k = 2; k <= Math.Ceiling(Math.Sqrt(number)); k++)
{
if (number > k && number % k == 0)
break;
if (k >= Math.Ceiling(Math.Sqrt(number)) || number == k)
{
return true;
}
}
return false;
}
Prime Numbers from 0 - 1 Million in less than two tenths of a second
Just finished it. Last test was 0.017 seconds.
Regular HP Laptop. 2.1 GHz
It takes longer when it gets larger. For primes 1 - 1 billion , my last test was 28.6897 seconds. It might be faster in your program because I was casting class objects to get parameter values in mine.
Method Info
Uses the Sieve of Eratosthenes
Accepts floor and ceiling as arguments
Uses arrays instead of lists for fast performance
Size of array is initialized according to Rosser-Schoenfeld upper bound
Skips multiples of 2, 5, and 7 when assigning values
Max range is between 0 and 2,147,483,646 (1 min 44.499 s)
Heavily commented
Using
using System;
using System.Diagnostics;
using System.Collections;
Method
private static int[] GetPrimeArray(int floor, int ceiling)
{
// Validate arguments.
if (floor > int.MaxValue - 1)
throw new ArgumentException("Floor is too high. Max: 2,147,483,646");
else if (ceiling > int.MaxValue - 1)
throw new ArgumentException("Ceiling is too high. Max: 2,147,483,646");
else if (floor < 0)
throw new ArgumentException("Floor must be a positive integer.");
else if (ceiling < 0)
throw new ArgumentException("Ceiling must be a positve integer.");
else if (ceiling < floor)
throw new ArgumentException("Ceiling cannot be less than floor.");
// This region is only useful when testing performance.
#region Performance
Stopwatch sw = new Stopwatch();
sw.Start();
#endregion
// Variables:
int stoppingPoint = (int)Math.Sqrt(ceiling);
double rosserBound = (1.25506 * (ceiling + 1)) / Math.Log(ceiling + 1, Math.E);
int[] primeArray = new int[(int)rosserBound];
int primeIndex = 0;
int bitIndex = 4;
int innerIndex = 3;
// Handle single digit prime ranges.
if (ceiling < 11)
{
if (floor <= 2 && ceiling >= 2) // Range includes 2.
primeArray[primeIndex++] = 2;
if (floor <= 3 && ceiling >= 3) // Range includes 3.
primeArray[primeIndex++] = 3;
if (floor <= 5 && ceiling >= 5) // Range includes 5.
primeArray[primeIndex++] = 5;
return primeArray;
}
// Begin Sieve of Eratosthenes. All values initialized as true.
BitArray primeBits = new BitArray(ceiling + 1, true);
primeBits.Set(0, false); // Zero is not prime.
primeBits.Set(1, false); // One is not prime.
checked // Check overflow.
{
try
{
// Set even numbers, excluding 2, to false.
for (bitIndex = 4; bitIndex < ceiling; bitIndex += 2)
primeBits[bitIndex] = false;
}
catch { } // Break for() if overflow occurs.
}
// Iterate by steps of two in order to skip even values.
for (bitIndex = 3; bitIndex <= stoppingPoint; bitIndex += 2)
{
if (primeBits[bitIndex] == true) // Is prime.
{
// First position to unset is always the squared value.
innerIndex = bitIndex * bitIndex;
primeBits[innerIndex] = false;
checked // Check overflow.
{
try
{
// Set multiples of i, which are odd, to false.
innerIndex += bitIndex + bitIndex;
while (innerIndex <= ceiling)
{
primeBits[innerIndex] = false;
innerIndex += bitIndex + bitIndex;
}
}
catch { continue; } // Break while() if overflow occurs.
}
}
}
// Set initial array values.
if (floor <= 2)
{
// Range includes 2 - 5.
primeArray[primeIndex++] = 2;
primeArray[primeIndex++] = 3;
primeArray[primeIndex++] = 5;
}
else if (floor <= 3)
{
// Range includes 3 - 5.
primeArray[primeIndex++] = 3;
primeArray[primeIndex++] = 5;
}
else if (floor <= 5)
{
// Range includes 5.
primeArray[primeIndex++] = 5;
}
// Increment values that skip multiples of 2, 3, and 5.
int[] increment = { 6, 4, 2, 4, 2, 4, 6, 2 };
int indexModulus = -1;
int moduloSkipAmount = (int)Math.Floor((double)(floor / 30));
// Set bit index to increment range which includes the floor.
bitIndex = moduloSkipAmount * 30 + 1;
// Increase bit and increment indicies until the floor is reached.
for (int i = 0; i < increment.Length; i++)
{
if (bitIndex >= floor)
break; // Floor reached.
// Increment, skipping multiples of 2, 3, and 5.
bitIndex += increment[++indexModulus];
}
// Initialize values of return array.
while (bitIndex <= ceiling)
{
// Add bit index to prime array, if true.
if (primeBits[bitIndex])
primeArray[primeIndex++] = bitIndex;
checked // Check overflow.
{
try
{
// Increment. Skip multiples of 2, 3, and 5.
indexModulus = ++indexModulus % 8;
bitIndex += increment[indexModulus];
}
catch { break; } // Break if overflow occurs.
}
}
// Resize array. Rosser-Schoenfeld upper bound of π(x) is not an equality.
Array.Resize(ref primeArray, primeIndex);
// This region is only useful when testing performance.
#region Performance
sw.Stop();
if (primeArray.Length == 0)
Console.WriteLine("There are no prime numbers between {0} and {1}",
floor, ceiling);
else
{
Console.WriteLine(Environment.NewLine);
for (int i = 0; i < primeArray.Length; i++)
Console.WriteLine("{0,10}:\t\t{1,15:#,###,###,###}", i + 1, primeArray[i]);
}
Console.WriteLine();
Console.WriteLine("Calculation time:\t{0}", sw.Elapsed.ToString());
#endregion
return primeArray;
}
Comments are welcome! Especially improvements.
Here we must have to consider the square root factor. A prime number can be verified if it is not divisible by any number less than the value of square root of any near number.
static bool isPrime(long number)
{
if (number == 1) return false;
if (number == 2) return true;
if (number % 2 == 0) return false; //Even number
long nn= (long) Math.Abs(Math.Sqrt(number));
for (long i = 3; i < nn; i += 2) {
if (number % i == 0) return false;
}
return true;
}

Categories

Resources