Function to check numbers are prime numbers - c#

I need to be able to check that two numbers entered by the user (p and q) are prime numbers, and if they aren't prime numbers then the user is asked to re-enter a prime number until a prime number has been entered for both p and q. If I enter a number which isn't a prime number, I am asked to enter another number, if I enter a prime number the second time round it tells me the prime number isn't a prime number. How can I correct this.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Math;
using System.Numerics;
namespace primenumbers
{
class Program
{
int Check_Prime(BigInteger p)
{
if (p <= 1) return 0;
for (int i = 2; i <= p / 2; i++)
{
if (p % i == 0)
{
return 0; //not a prime number
}
}
return 1;
}
static void result (BigInteger p)
{
int result = Check_Prime(p);
if (Check_Prime(p) != 0)
{
Console.WriteLine(" is a prime number");
}
else do
{
Console.WriteLine(" is not a prime number");
Console.WriteLine("Please enter a prime number");
p = BigInteger.Parse(Console.ReadLine());
} while (result == 0);
}
static int Check_Prime_Q(BigInteger q)
{
if (q <= 1) return 0;
for (int i = 2; i <= q / 2; i++)
{
if (q % i == 0)
{
return 0; //not a prime number
}
}
return 1;
}
static void resultq(BigInteger q)
{
int result = Check_Prime_Q(q);
if (Check_Prime_Q(q) != 0)
{
Console.WriteLine(" is a prime number");
}
else do
{
Console.WriteLine(" is not a prime number");
Console.WriteLine("Please enter a prime number");
q = BigInteger.Parse(Console.ReadLine());
} while (result == 0);
}
static void Main(string[] args)
{
BigInteger p; // = 61; //value of p
Console.WriteLine("Enter a prime number for p");
p = BigInteger.Parse(Console.ReadLine());
result(p);
BigInteger q; //53; //value of q
Console.WriteLine("Ener a prime number for q");
q = BigInteger.Parse(Console.ReadLine());
resultq(q);
result(p);
BigInteger n = p * q; // calculation for n
Console.WriteLine("p = " + p);
Console.WriteLine();
Console.WriteLine("q = " + q);
Console.WriteLine();
Console.WriteLine("n = " + n);
}
}
}

Apart from the fact that many things in the code could be improved (like naming, return values, p and q mistaken in Main) the main problem lays here. You are incrementing i to p/2 and right after that you are checking if (i == p) which is never going to be true (except for p = 0)
static int Check_Prime(BigInteger p)
{
int i;
for (i = 2; i <= p /2; i++)
{
if (p % i == 0)
{
return 0; //not a prime number
}
}
if (i == p) // never true except p == 0
{
return 1;
}
return 0; // always returns 0
}
Simply remove the if statement and return 1.
static int Check_Prime(BigInteger p)
{
if (p <= 1) return 0;
for (int i = 2; i <= p /2; i++)
{
if (p % i == 0)
{
return 0; //not a prime number
}
}
return 1;
}

Related

c# how to fill an array with user input

I'm creating a lottery program that users can choose from a series of numbers between a particular range and the program then creates its own version of numbers and compares those user values against the program's random numbers which any matches that the program then finds are then displayed to the user.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assessment1.Lottery
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Please insert 6 lottery numbers:");
int range = 100;
int minValue = 0;
int maxValue = 100;
int a = 0;
Random rnd = new Random();
int[] myArray = new int[6];
for ( int i=0; i < myArray.Length; i++ )
{
int randomNumber = rnd.Next(minValue, maxValue);
myArray[i] = randomNumber;
Console.WriteLine(randomNumber);
myArray[i] = int.Parse(Console.ReadLine());
Console.WriteLine(myArray[i]);
while (a < 5)
{
if (int.TryParse(Console.ReadLine(), out myArray[a]))
a++;
else
Console.WriteLine("invalid integer");
}
double arry = myArray.Average();
if(arry > 0)
Console.WriteLine("found");
else
Console.WriteLine("not found");
int BinarySearch(int[] array, int value, int low, int high)
{
if ( high >= low)
{
int mid = (low + high) / 2;
if (array[mid] == value) return mid;
if (array[mid] == value) return BinarySearch(array, value, low, mid - 1);
return BinarySearch(array, value, mid + 1, high);
}
return -1;
}
}
Console.ReadLine();
}
}
}
when I run the program it shows the following
Please insert 6 lottery numbers: 64
how can I fix this so that the array can be filled with user input
Here is a version of something I wrote a while back and modified to your parameters, if there are bugs please don't ask me to fix.
static void Main(string[] args)
{
int stop = 0;
int[] chosenNum = new int[6];
while (stop == 0)
{
Console.Clear();
string con = "";
Console.WriteLine("Enter six numbers between 1-100 separated by a comma with no duplicates:");
string numbers = Console.ReadLine();
string[] userNumbers = numbers.Replace(" ", "").Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).ToArray();;//remove ex: ,, issues
string[] checkDup = userNumbers.Distinct().ToArray();//remove duplicates
if (userNumbers.Count() < 6)
{
Console.WriteLine("You entered less than six numbers");
Console.WriteLine("Try Again Y or N");
con = Console.ReadLine();
if (con.ToUpper() != "Y")
{
stop = 1;
}
}
else if (userNumbers.Count() > 6)
{
Console.WriteLine("You entered more than 6 numbers");
Console.WriteLine("Try Again Y or N");
con = Console.ReadLine();
if (con.ToUpper() != "Y")
{
stop = 1;
}
}
else if (checkDup.Count() < 6)
{
Console.WriteLine("You entered duplicate numbers");
Console.WriteLine("Try Again Y or N");
con = Console.ReadLine();
if (con.ToUpper() != "Y")
{
stop = 1;
}
}
else if (!isNumeric(userNumbers))
{
Console.WriteLine("You entered non-numeric value(s)");
Console.WriteLine("Try Again Y or N");
con = Console.ReadLine();
if (con.ToUpper() != "Y")
{
stop = 1;
}
}
else if (isInRange(userNumbers) < 6)
{
Console.WriteLine("You entered out of range value(s)");
Console.WriteLine("Try Again Y or N");
con = Console.ReadLine();
if (con.ToUpper() != "Y")
{
stop = 1;
}
}
else
{
var lowerBound = 1;
var upperBound = 100;
var random = new Random();
int[] randomNum = new int[6];
int count = 0;
foreach(string str in userNumbers){
var rNum = random.Next(lowerBound, upperBound);
randomNum[count] = rNum;
count++;
}
string[] ourPicks = Array.ConvertAll(randomNum, s => s.ToString()).ToArray();
Array.Sort(userNumbers);
Array.Sort(ourPicks);
//string[] ourpicks = { "1", "2" };//for testing
Console.WriteLine("Your Numbers: {0}", string.Join(", ", userNumbers));
Console.WriteLine("Our Numbers: {0}", string.Join(", ", ourPicks));
string[] result = userNumbers.Intersect(ourPicks).ToArray();
if(result.Count() > 0)
{
Console.WriteLine("Matchs: {0}", string.Join(", ", result));
}
else
{
Console.WriteLine("Match's = 0");
}
stop = 1;
}
}
Console.ReadLine();
}
public static bool isNumeric(string[] num)
{
foreach (string str in num)
{
bool check = int.TryParse(str, out int test);
if (!check)
{
return false;
}
}
return true;
}
public static int isInRange(string[] num)
{
int count = 0;
foreach (string str in num)
{
int.TryParse(str, out int test);
if (test > 0 & test <= 100)
{
count++;
}
}
return count;
}

C# Collatz - Does anyone know a fix?

Hey does anyone have a fix for this? I don't know why i keep getting an error that the main-cs and compilation fails.
using System;
class MainClass {
public static void Main (string[] args) {
Console.WriteLine ("Length of Collatz Row");
int cn = Console.ReadLine();
CollatzListLength(cn);
}
public int CollatzListLength(n){
int number;
List<int> numbers = new List<int>();
while(n != 1){
if(n % 2 == 0){
number = n/2;
}
if(n%2 ==1){
number = n*3 + 1;
}
n = number;
numbers.Add(number);
}
return numbers.Count;
}
Console.ReadLine() returns a string, not an int.
CollatzListLength needs to be static and the parameter needs to be declared as int
n = number; doesn't work because number may never be assigned a value. Use else instead of if (n % 2 == 1) as it just checks the other possible condition anyway.
In total:
static void Main(string[] args)
{
Console.WriteLine("Length of Collatz Row");
if (int.TryParse(Console.ReadLine(), out int cn))
CollatzListLength(cn);
else
Console.WriteLine("Needs a number");
}
public static int CollatzListLength(int n)
{
int number;
List<int> numbers = new List<int>();
while (n != 1)
{
if (n % 2 == 0)
{
number = n / 2;
}
else
{
number = n * 3 + 1;
}
n = number;
numbers.Add(number);
}
return numbers.Count;
}
I haven't actually checked the sanity of the code though.
An alternative, repaired to compile without error messages:
using System;
using System.Collections.Generic;
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Length of Collatz Row");
int cn = int.Parse(Console.ReadLine());
int len = CollatzListLength(cn);
Console.WriteLine($"len {len}");
}
public static int CollatzListLength(int n)
{
int number = 0;
List<int> numbers = new List<int>();
while (n != 1)
{
if (n % 2 == 0)
{
number = n / 2;
}
if (n % 2 == 1)
{
number = n * 3 + 1;
}
n = number;
numbers.Add(number);
}
return numbers.Count;
}
}

c# subtract a number from an array index in a for loop

I need to find the difference of each number value in an array from an average value. I need to loop through each value and subtract each value FROM the average and display the difference. I have tried several different ways but the difference always comes out as 0 at the end. What am i doing wrong here?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Console;
namespace AvgNDiff
{
class Program
{
static void Main(string[] args)
{
int[] numbers = new int[10];
int x = 0;
int i;
string entryString = "";
int counter = 0;
int countdown = 10;
int sum = 0;
int average = 0;
while (counter < numbers.Length && numbers[x] != 10 && entryString != "0")
{
if (x == 0)
Write("Enter up to 10 numbers or type 0 to stop > ");
else if (x == 9)
Write("Enter {0} more number or type 0 to stop > ", countdown);
else
Write("Enter up to {0} more numbers or type 0 to stop > ", countdown);
entryString = ReadLine();
numbers[x] = Convert.ToInt32(entryString);
if (entryString != "0")
{
sum += numbers[x];
counter++;
x++;
}
countdown--;
}
average = sum / x;
WriteLine("\n\nYou entered {0} numbers with a sum of {1}", x, sum);
WriteLine("The average of your numbers is " + average);
WriteLine("\n\nNumber Difference");
WriteLine("-------------------------------");
for (i=0; i < x; i++)
{
int value = numbers[i];
int diff = average-value;
WriteLine(String.Format("{0,-10} {1,-10}", (numbers[i]), diff));
}
ReadKey();
}
}
}
Take a look here
int value = numbers[i];
int diff = value - average;
WriteLine(String.Format("{0,-10} {1,-10}", (numbers[i]), value));
the key issue here is the writeline statement.
Youve told it to display numbers[i], and oh wait.. numbers[i] (as thats what value is)
yet diff contains the variance from the average...
static void Main(string[] args)
{
List<int> numberList = new List<int>();
Console.WriteLine("Enter up to 10 numbers or type 0 to stop:");
for (int i = 0; i < 10; i++)
{
int userInput = 0;
while (!int.TryParse(Console.ReadLine(), out userInput))
{
Console.WriteLine("Only integer numbers accepted, let's try again...:");
}
if (userInput == 0)
{
break;
}
else
{
numberList.Add(userInput);
if (i < 9)
{
Console.WriteLine("Yeah, {0} more number{1} to go!", (9 - i), (i == 8 ? "" : "s"));
}
}
}
double average = numberList.Average();
for (int i = 0; i < numberList.Count; i++)
{
Console.WriteLine("#{0}: {1} - {2} = {3}", (i+1), numberList[i], average, (numberList[i] - average));
}
Console.ReadLine();
}
Do not cram the entire soultion into the single Main, extract (and debug) a method:
// Subtract each item from the average
private static double[] MyNormalize(int[] source) {
double sum = 0.0;
foreach (var item in source)
sum += item;
double[] result = new double[source.Length];
for (int i = 0; i < source.Length; ++i)
result[i] = sum / source.Length - source[i];
return result;
}
...
static void Main(string[] args) {
int[] numbers = new int[10];
...
// Input
while (counter < numbers.Length && numbers[x] != 10 && entryString != "0") {
...
entryString = ReadLine();
numbers[x] = Convert.ToInt32(entryString);
}
// Business logic
double[] norm = MyNormalize(numbers);
// Output
for (int i = 0; i < numbers.Length; ++i)
WriteLine(String.Format("{0,-10} {1,-10}", numbers[i], norm[i]));
}

Number of zeroes at the end of factorial

I need to find the number of zeroes at the end of a factorial number. So here is my code, but it doesn't quite work :/
using System;
class Sum
{
static void Main(string[] args)
{
int n = int.Parse(Console.ReadLine());
long factoriel = 1;
for (int i = 1; i <= n; i++)
{
factoriel *= i;
}
Console.WriteLine(factoriel);
int timesZero = 0;
while(factoriel % 10 != 0)
{
timesZero++;
}
Console.WriteLine(timesZero);
}
}
I know I can use a for loop and divide by 5, but I don't want to. Where is the problem in my code and why isn't it working?
There's problem with your algorithm: integer overflow. Imagine, that you are given
n = 1000
and so n! = 4.0238...e2567; you should not compute n! but count its terms that are in form of (5**p)*m where p and m are some integers:
5 * m gives you one zero
25 * m gives you two zeros
625 * m gives you three zeros etc
The simplest code (which is slow on big n) is
static void Main(string[] args) {
...
int timesZero = 0;
for (int i = 5; i <= n; i += 5) {
int term = i;
while ((term % 5) == 0) {
timesZero += 1;
term /= 5;
}
}
...
}
Much faster implementation is
static void Main(string[] args) {
...
int timesZero = 0;
for (int power5 = 5; power5 <= n; power5 *= 5)
timesZero += n / power5;
...
}
Counting Trailing zeros in Factorial
static int countZerosInFactOf(int n)##
{
int result = 0;
int start = 1;
while (n >= start)
{
start *= 5;
result += (int)n/start;
}
return result;
}
Make sure to add inbuilt Reference System.Numeric
using System.Text;
using System.Threading.Tasks;
using System.Numeric
namespace TrailingZeroFromFact
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter a no");
int no = int.Parse(Console.ReadLine());
BigInterger fact = 1;
if (no > 0)
{
for (int i = 1; i <= no; i++)
{
fact = fact * i;
}
Console.WriteLine("{0}!={1}", no, fact);
string str = fact.ToString();
string[] ss = str.Split('0');
int count = 0;
for (int i = ss.Length - 1; i >= 0; i--)
{
if (ss[i] == "")
count = count + 1;
else
break;
}
Console.WriteLine("No of trailing zeroes are = {0}", count);
}
else
{
Console.WriteLine("Can't calculate factorial of negative no");
}
Console.ReadKey();
}
}
}
static void Main(string[] args)
{
Console.WriteLine("Enter the number:");
int n = int.Parse(Console.ReadLine());
int zero = 0;
long fac=1;
for (int i = 1; i <= n; i++)
{
fac *= i;
}
Console.WriteLine("Factorial is:" + fac);
ab:
if (fac % 10 == 0)
{
fac = fac / 10;
zero++;
goto ab;
}
else
{
Console.WriteLine("Zeros are:" + zero);
}
Console.ReadLine();
}
Your code seems fine, just a little correction in the while-condition:
public static int CalculateTrailingZeroes(BigInteger bigNum)
{
int zeroesCounter = 0;
while (bigNum % 10 == 0)
{
zeroesCounter++;
bigNum /=10;
}
return zeroesCounter;
}
That works, I just tested it.

n-th prime number problem, need to speed it up a bit

There is simple cipher that translates number to series of . ( )
In order to encrypt a number (0 .. 2147483647) to this representation, I (think I) need:
prime factorization
for given p (p is Prime), order sequence of p (ie. PrimeOrd(2) == 0, PrimeOrd(227) == 49)
Some examples
0 . 6 (()())
1 () 7 (...())
2 (()) 8 ((.()))
3 (.()) 9 (.(()))
4 ((())) 10 (().())
5 (..()) 11 (....())
227 (................................................())
2147483648 ((..........()))
My source code for the problem
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
static class P
{
static List<int> _list = new List<int>();
public static int Nth(int n)
{
if (_list.Count == 0 || _list.Count < n)
Primes().Take(n + 1);
return _list[n];
}
public static int PrimeOrd(int prime)
{
if (_list.Count == 0 || _list.Last() < prime)
Primes().First(p => p >= prime);
return (_list.Contains(prime)) ? _list.FindIndex(p => p == prime) : -1;
}
public static List<int> Factor(int N)
{
List<int> ret = new List<int>();
for (int i = 2; i ≤ N; i++)
while (N % i == 0)
{
N /= i;
ret.Add(i);
}
return ret;
}
public static IEnumerable<int> Primes()
{
_list = new List<int>();
_list.Add(2);
yield return 2;
Func<int, bool> IsPrime = n => _list.TakeWhile(p => p ≤ (int)Math.Sqrt(n)).FirstOrDefault(p => n % p == 0) == 0;
for (int i = 3; i < Int32.MaxValue; i += 2)
{
if (IsPrime(i))
{
_list.Add(i);
yield return i;
}
}
}
public static string Convert(int n)
{
if (n == 0) return ".";
if (n == 1) return "()";
StringBuilder sb = new StringBuilder();
var p = Factor(n);
var max = PrimeOrd(p.Last());
for (int i = 0; i ≤ max; i++)
{
var power = p.FindAll((x) => x == Nth(i)).Count;
sb.Append(Convert(power));
}
return "(" + sb.ToString() + ")";
}
}
class Program
{
static void Main(string[] args)
{
string line = Console.ReadLine();
try
{
int num = int.Parse(line);
Console.WriteLine("{0}: '{1}'", num, P.Convert(num));
}
catch
{
Console.WriteLine("You didn't entered number!");
}
}
}
The problem is SLOWNESS of procedure PrimeOrd. Do you know some FASTER solution for finding out order of prime in primes?
Heading
If You know how to speed-up finding order of prime number, please, suggest something. :-)
Thank You.
P.S. The biggest prime less than 2,147,483,648 is 2,147,483,647 and it's 105,097,565th prime. There is no need to expect bigger number than 2^31.
This is not something you should be doing at run-time. A better option is to pre-calculate all these primes and then put them in your program somehow (a static array, or a file to be read in). The slow code is then run as part of the development process (which is slow anyway :-), not at the point where you need your speed.
Then it's just a matter of a lookup of some sort rather than calculating them every time you need them.
Please see SO questions:
http://www.google.com/search?q=site%3Astackoverflow.com+prime+number&btnG=Search
Finding prime numbers with the Sieve of Eratosthenes (Originally: Is there a better way to prepare this array?)
Prime number calculation fun
How can I find prime numbers through bit operations in C++?
prime numbers c#
Finding composite numbers
Prime numbers program
If you need a list of known primes, have a look here
You should cache the primes to _list and then use it for both Factor and PrimeOrd. Additionally avoid operators LINQ operators like TakeWhile that create values that you throw away.
Here's an optimized version:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
static class P
{
private static List<int> _list = new List<int>();
public static int Nth(int n)
{
if (_list.Count == 0 || _list.Count <= n)
{
GenerateNextPrimes().First(p => _list.Count >= n);
}
return _list[n];
}
public static int PrimeOrd(int prime)
{
var primes = GrowPrimesTo(prime);
return primes.IndexOf(prime);
}
public static List<int> Factor(int N)
{
List<int> ret = new List<int>();
GrowPrimesTo(N);
for (int ixDivisor = 0; ixDivisor < _list.Count; ixDivisor++)
{
int currentDivisor = _list[ixDivisor];
while (N % currentDivisor == 0)
{
N /= currentDivisor;
ret.Add(currentDivisor);
}
if (N <= 1)
{
break;
}
}
return ret;
}
private static List<int> GrowPrimesTo(int max)
{
if (_list.LastOrDefault() >= max)
{
return _list;
}
GenerateNextPrimes().First(prime => prime >= max);
return _list;
}
private static IEnumerable<int> GenerateNextPrimes()
{
if (_list.Count == 0)
{
_list.Add(2);
yield return 2;
}
Func<int, bool> IsPrime =
n =>
{
// cache upperBound
int upperBound = (int)Math.Sqrt(n);
for (int ixPrime = 0; ixPrime < _list.Count; ixPrime++)
{
int currentDivisor = _list[ixPrime];
if (currentDivisor > upperBound)
{
return true;
}
if ((n % currentDivisor) == 0)
{
return false;
}
}
return true;
};
// Always start on next odd number
int startNum = _list.Count == 1 ? 3 : _list[_list.Count - 1] + 2;
for (int i = startNum; i < Int32.MaxValue; i += 2)
{
if (IsPrime(i))
{
_list.Add(i);
yield return i;
}
}
}
public static string Convert(int n)
{
if (n == 0) return ".";
if (n == 1) return "()";
StringBuilder sb = new StringBuilder();
var p = Factor(n);
var max = PrimeOrd(p.Last());
for (int i = 0; i <= max; i++)
{
var power = p.FindAll(x => x == Nth(i)).Count;
sb.Append(Convert(power));
}
return "(" + sb.ToString() + ")";
}
}
class Program
{
static void Main(string[] args)
{
string line = Console.ReadLine();
int num;
if(int.TryParse(line, out num))
{
Console.WriteLine("{0}: '{1}'", num, P.Convert(num));
}
else
{
Console.WriteLine("You didn't entered number!");
}
}
}

Categories

Resources