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

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.

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

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

Checking for a prime number

I'm having problems with a task. I need to find and alert the user if the number is prime or not.
Here is my code:
int a = Convert.ToInt32(number);
if (a % 2 !=0 )
{
for (int i = 2; i <= a; i++)
{
if (a % i == 0)
{
Console.WriteLine("not prime");
}
else
{
Console.WriteLine("prime");
}
Console.WriteLine();
}
}
else
{
Console.WriteLine("not prime");
}
Console.ReadLine();
Where did I go wrong, and how can I fix it?
Prime numbers is divisible by 1 and themselves you will need to check if number has exactly two divisor starting from one till number then it is prime.
int devisors = 0;
for (int i = 1; i <= a; i++)
if (a % i == 0)
devisors++;
if (devisors == 2)
Console.WriteLine("prime");
else
Console.WriteLine("not prime");
You can skip one iteration as we know all whole numbers are divisible by 1 then you will have exactly on divisor for prime numbers. Since 1 has only one divisor we need to skip it as it is not prime. So condition would be numbers having only one divisor other then 1 and number should not be one as one is not prime number.
int devisors = 0;
for (int i = 2; i <= a; i++)
if (a % i == 0)
devisors++;
if (a != 1 && devisors == 1)
Console.WriteLine("prime");
else
Console.WriteLine("not prime");
You just printed prime or not prime, and continued with the loop, rather than stopping. The %2 check is not really needed. Modified appropriately:
int a = Convert.ToInt32(number);
bool prime = true;
if (i == 1) prime = false;
for (int i = 2; prime && i < a; i++)
if (a % i == 0) prime = false;
if (prime) Console.WriteLine("prime");
else Console.WriteLine("not prime");
Console.ReadLine();
public bool isPrime(int num)
{
for (int i = 2; i < num; i++)
if (num % i == 0)
return false;
return num == 1 ? false : true;
}
Presumably your code is outputting lots of messages, which seem jumbled and meaningless? There are 3 key issues:
You arn't breaking out of your for loop when you've decided it can't be prime
You are assuming it is prime when it might not be, see the comments in the code below.
You are comparing to a itself, and that will always be divisible by a, the <= in the for condition needs to be <
Code:
int a = Convert.ToInt32(number);
if (a % 2 != 0)
{
for (int i = 3 i < a; i += 2) // we can skip all the even numbers (minor optimization)
{
if (a % i == 0)
{
Console.WriteLine("not prime");
goto escape; // we want to break out of this loop
}
// we know it isn't divisible by i or any primes smaller than i, but that doesn't mean it isn't divisible by something else bigger than i, so keep looping
}
// checked ALL numbers, must be Prime
Console.WriteLine("prime");
}
else
{
Console.WriteLine("not prime");
}
escape:
Console.ReadLine();
As other have mentioned, you could only loop to the square root of the a, by per-evaluating the square root and replacing this line:
for (int i = 3 i < a; i += 2)
with this:
float sqrRoot = (Int)Math.Sqrt((float)a);
for (int i = 3 i <= sqrRoot; i += 2)
It is important to per-evaluate it else your program will run much slower, rather than faster, as each iteration will involve a square root operation.
If you don't like goto statements (I love goto statements), post a comment and I'll replace it will a breakout boolean (or see Dukeling's more recent answer).
I've done far too much prime checking.
I did this:
bool isPrime = true;
List<ulong> primes = new List<ulong>();
ulong nCheck, nCounted;
nCounted = 0;
nCheck = 3;
primes.Add(2);
for (; ; )
{
isPrime = true;
foreach (ulong nModulo in primes)
{
if (((nCheck / 2) + 1) <= nModulo)
{ break; }
if (nCheck % nModulo == 0)
{ isPrime = false; }
}
if (isPrime == true)
{
Console.WriteLine("New prime found: " + (nCheck) + ", prime number " + (++nCounted) + ".");
primes.Add(nCheck);
}
nCheck++;
nCheck++;
}
This is not EXACTLY what you are looking for though, so what I'd do is put this in a background worker, but with the list of ulongs as a concurrent list, or something that you can access in 2 threads. Or just lock the list while it's being accessed. If the prime hssn't been worked out yet, wait until it is.
Yet another optimized way is to use Sieve of Eratosthenes algorithm.
From Wikipedia
To find all the prime numbers less than or equal to a given integer n by Eratosthenes' method:
1. Create a list of consecutive integers from 2 to n: (2, 3, 4, ..., n).
2. Initially, let p equal 2, the first prime number.
3. Starting from p, count up in increments of p and mark each of these numbers greater than p itself in the list. These will be multiples of p: 2p, 3p, 4p, etc.; note that some of them may have already been marked.
4. Find the first number greater than p in the list that is not marked. If there was no such number, stop. Otherwise, let p now equal this number (which is the next prime), and repeat from step 3.
When the algorithm terminates, all the numbers in the list that are not marked are prime.
C# code
int[] GetPrimes(int number) // input should be greater than 1
{
bool[] arr = new bool[number + 1];
var listPrimes = new List<int>();
for (int i = 2; i <= Math.Sqrt(number); i++)
{
if (!arr[i])
{
int squareI = i * i;
for (int j = squareI; j <= number; j = j + i)
{
arr[j] = true;
}
}
for (int c = 1; c < number + 1; c++)
{
if (arr[c] == false)
{
listPrimes.Add(c);
}
}
}
return listPrimes.ToArray();
}
private static void checkpirme(int x)
{
for (int i = 1; i <= x; i++)
{
if (i == 1 || x == i)
{
continue;
}
else
{
if (x % i == 0)
{
Console.WriteLine(x + " is not prime number");
return;
}
}
}
Console.WriteLine(x + " is prime number");
}
where x is number to check it if prime or not

Fast prime numbers between range

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.

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