Finding the nth prime in the set of prime numbers. - c#

This application will receive a number "n". After receiving this number, the program has to show the nth prime in the list of primes. For example, if the user enters "3", the program is supposed to display "5", because 5 is the third prime starting at 2. I know that something is wrong with my code but I don't know where the problem is and how I can fix it.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Determinar el n-esimo primo.");
long n = Convert.ToInt64(Console.ReadLine()); // N lugar de primos
long[] array = new long[n];
long c=0;
while (c >= 2)
{
if(siprimo(c++) == true)
for (long i = 0; i < n; i++)
{
array[i] = c;
}
}
Console.WriteLine(array[n - 1]);
Console.ReadLine();
}
static private bool siprimo(long x)
{
bool sp = true;
for (long k = 2; k <= x / 2; k++)
if (x % k == 0)
sp = false;
return sp;
}
}
}

This looks like homework, and I'm not going to do your homework for you. But I will tell you that the problem is VERY easy to find if you simply STEP THROUGH your program (use F10 in Visual Studio).
Hint: When does c get incremented?

Some other questions to ask yourself:
when a prime number is found (siprime), where does the value get stored?
how many times are you looping through the while (c >= 2) code block?

More like:
int GetAnswer(int nprime) {
if (nprime == 1) return 2;
if (nprime == 2) return 3;
int j;
int n = 2;
int i = 5;
while (n < nprime) {
int isprime = 1;
double r = Math.Sqrt(i);
for(j = 3; j <= r; j+=2)
if((i%j) == 0) {
isprime = 0;
break;
}
n+=isprime;
i+=2;
}
return i;
}
In your program you made some mistakes like:
long c=0;
while (c >= 2)
C is never greater than 2 so the code never gets executed.

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.

Trying to find the 10001st prime number, c#

I am trying to "Find the 10001st prime number" as part of the Project Euler challenges and i have no idea why my code doesn't work. When I tested my isPrime() function, it succeeded in finding whether a number was prime, but my program returns 10200 as the 10001st prime. Why is this?
Here is My Code:
using System;
using System.Collections.Generic;
namespace Challenge_7
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Solution to Project Euler");
Console.WriteLine("Challenge 7 - Find the 10001st prime");
Console.WriteLine("\nProject Start:");
List<int> primes = new List<int>();
int number = 1;
while (primes.Count != 10001)
{
if (isPrime(number))
{
primes.Add(number);
Console.WriteLine(number);
}
number++;
}
Console.WriteLine("The 10001st prime is: {0}", primes[10000]);
Console.ReadLine();
}
private static bool isPrime(int n)
{
bool prime = true;
for (int i = 1; i <= Math.Ceiling(Math.Sqrt(n)); i++)
{
for (int j = 1; j <= Math.Ceiling(Math.Sqrt(n)); j++)
{
if (i * j == n)
{
prime = false;
}
}
}
return prime;
}
}
}
Here's a hint::
Imagine a number that is the product of 3 primes.
Lets say 3, 5, and 7 (or) 105;
sqrt(105) == 10.2 so ceiling is 11
There aren't two numbers less than 11 that multiply to 105.
So your algorithm would falsely return true!
Try Again! :-D
The problem is in you loops. Math.Ceiling(Math.Sqrt(10200)) is 101 and you need to check 102 * 100 = 10200 but your loops never reaches 102 and returns 10200 as prime!
You can use the code below for isPrime. It is exists in this link and I changed to C# for you:
private static bool isPrime(int n)
{
if (n <= 1)
return false;
else if (n <= 3)
return true;
else if (n % 2 == 0 || n % 3 == 0)
return false;
int i = 5;
while (i * i <= n)
{
if (n % i == 0 || n % (i + 2) == 0)
return false;
i += 6;
}
return true;
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace nthPrimeNumber
{
class Program
{
static void Main(string[] args)
{
ulong starting_number = 1;
ulong last_number = 200000; //only this value needs adjustment
ulong nth_primenumber = 0;
ulong a;
ulong b;
ulong c;
for (a = starting_number; a <= last_number; a++)
{
b = Convert.ToUInt64(Math.Ceiling(Math.Sqrt(a)));
for (c = 2; c <= b; c++)
{
if (a == 1 || (a % c == 0 && c != b))
{
break;
}
else
{
if (c == b)
{
nth_primenumber = nth_primenumber + 1;
break;
}
}
}
if (nth_primenumber == 10001)
{
break;
}
}
Console.WriteLine(nth_primenumber + "st" + "prime number is " + a);
Console.ReadKey();
}
}
}
The program above generates prime numbers between 1 and 200000. The program counts the generated prime numbers and checks if the generated prime numbers are already 10001. The program prints the 10001st prime number. If the program doesn't show 10001st (or shows below 10001) in the console, it is because the value of the last_number is small -- then try to adjust the value of the last_number (make it bigger). In this program, I have already adjusted the value of the last_number and will print the 10001st prime number.

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

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