code for finding biggest factor of the number - c#

I'm improving my C# skills and now I'm writing code for finding biggest factor of the number. However, it doesn't display anything
static void Main(string[] args)
{
Int64 a = 600851475143;
List<Int64> dividers = new List<Int64>();
for (Int64 b = 2; b < a; b++)
{
if (a % b == 0)
{
dividers.Add(b);
}
}
Int64 max = dividers.Max();
Console.WriteLine(max);
Console.ReadLine();
}

Your program works fine - it just takes a really long time to execute. You need to find a more efficient means of doing this.
A trick you can use is to only factor up to the square root - factors always come in pairs.
Int64 a = 600851475143;
List<Int64> dividers = new List<Int64>();
for (Int64 b = 2; b <= Math.Sqrt(a); b++)
{
if (a % b == 0)
{
dividers.Add(b);
dividers.Add(a / b);
}
}
Int64 max = dividers.Max();
You can further improve this - you can instead of keeping a list of all of the factors, just keep track of the biggest one seen so far.

Knowing now that you're trying to solve Euler Problem 3 I'm not going to give a direct answer.
Things to consider when solving this problem:
## 1 ##
You only have to check up to the sqrt() of that number.
double limit = Math.Sqrt(number);
for (int i = 2; i <= limit; i++)
## 2 ## An IsPrime function
public static bool IsPrime(long number)
{
if ((number & 1) == 0)
{
return number == 2;
}
double limit = Math.Sqrt(number);
for (int i = 3; i <= limit; i += 2)
{
if ((number % i) == 0)
{
return false;
}
}
return number != 1;
}
## 3 ##
When you find a factor (a % b == 0), check if b or (a/b) are prime and keep the largest one that exceeds the currently known largest prime factor

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.

'Summation of primes' takes too long [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I don't know why this takes forever for big numbers I'm trying to solve Problem 10 in Project Euler (https://projecteuler.net/problem=10). Can someone help me please?
It finds the first prime number and crosses all its factors, Then moves on to the next prime number and so on.
long sum=0;
int howmanyChecked = 1;
int target = 1000000;
int index = -1;
List<int> numbers = new List<int>(target);
List<bool> Isprime = new List<bool>(target);
for(int i=2;i<=target;i++)
{
numbers.Add(i);
Isprime.Add(true);
}
while (1 > 0)
{
index = Isprime.IndexOf(true, index + 1);
int Selected = numbers[index];
howmanyChecked++;
sum += Selected;
//Console.WriteLine($"selected prime number is {Selected}");
//int startfrom =numbers.IndexOf(Selected * Selected);
if (Selected >= target / 2)
{
Console.WriteLine("ss");
for(int i=index+1;i<target-1;i++)
{
if(Isprime[i]==true)
{
Console.WriteLine(numbers[i].ToString());
sum += numbers[i];
}
}
Console.WriteLine($"the sum of all prime nubers below {target} is {sum} tap to continue");
Console.ReadLine();
break;
}
else
{
for (int i = Selected; i * Selected <= target; i++)
{
int k = numbers.IndexOf(i * Selected);
if (k == -1)
break;
if (Isprime[k] == true)
{
Isprime[numbers.IndexOf(i * Selected)] = false;
howmanyChecked++;
//Console.WriteLine($"Checked number is {Selected * i} and we have counted {howmanyChecked} numbers");
}
}
}
if (howmanyChecked == target || index==target)
break;
}
Console.ReadLine();
Apply some straightforward optimizations:
list numbers should not be used because each number can be calculated based on an index
simplified initialization of Isprime.
For 1'000'000 got:
the sum of all prime numbers below 1000000 is 37548466742 tap to continue
long sum = 0;
int howmanyChecked = 1;
int target = 1000000;
int index = -1;
var Isprime = Enumerable.Repeat(true, target).ToArray();
while (1 > 0)
{
index = Array.IndexOf(Isprime, true, index + 1);
int Selected = index + 2;
howmanyChecked++;
sum += Selected;
//Console.WriteLine($"selected prime number is {Selected}");
//int startfrom =numbers.IndexOf(Selected * Selected);
if (Selected >= target / 2)
{
Console.WriteLine("ss");
for (int i = index + 1; i < target - 1; i++)
{
if (Isprime[i] == true)
{
Console.WriteLine(i + 2);
sum += i + 2;
}
}
Console.WriteLine($"the sum of all prime nubers below {target} is {sum} tap to continue");
Console.ReadLine();
break;
}
else
{
for (int i = Selected; i * Selected <= target; i++)
{
int k = i * Selected - 2;
if (k < 0)
break;
if (Isprime[k] == true)
{
Isprime[k] = false;
howmanyChecked++;
//Console.WriteLine($"Checked number is {Selected * i} and we have counted {howmanyChecked} numbers");
}
}
}
if (howmanyChecked == target || index == target)
break;
}
Console.ReadLine();
Do SoE (Sieve of Eratosthenes) up to n=2000000 in case you want to be memory efficient 2000000/16 = 62500 Bytes as you need just one bit per odd number). You can do the sum while filling SoE.
Your description is a SoE but you got too much code for a SoE ... my simple SoE solution for this is just 11 lines of formatted C++ code where half of it is variables declaration:
const DWORD N=2000000; // ~ 36 ms
const DWORD M=N>>1; // store only odd values from 3,5,7,...
char p[M]; // p[i] -> is 1+i+i prime? (factors map)
DWORD i,j,k,ss=0,n=0x10000000-N;
uint<2> s=2;
p[0]=0; for (i=1;i<M;i++) p[i]=1;
for(i=3,j=i>>1;i<N;i+=2,j++)
{
if (p[j]==1) { ss+=i; if (ss>=n) { s+=DWORD(ss); ss=0; }}
for(k=i+j;k<M;k+=i) p[k]=0;
} s+=DWORD(ss);
// s holds the answer 142913828922
where DWORD is unsigned 32bit int and uint<2> is 64bit unsigned int (as I am still on 32bit compiler that is why I do the sum so weirdly). As you can see you got maybe 3 times more code than necessary.
Using IsPrime without memoization is too slow but even with memoization can never beat SoE. see:
Prime numbers by Eratosthenes quicker sequential than concurrently?
btw. I got my Euler projects in single app where I do SoE up to 10^7 which creates a list of all primes up to 10^7 this takes 130 ms on my pretty old PC and that is then used for all the Euler problems related to primes (which speeds them up so the first 40 problems is finished below 1sec) which for this case (different solution code) takes 0.7 ms.
To avoid overflows sum on 64 bit arithmetics.
Also using dynamic lists without pre-allocation is slow. You do not need them anyway.
Try with this:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
int main()
{
int n,i,i1,imax;
long sumprime;
bool *prime5mod6,*prime1mod6;
n=2000000;
imax=(n-n%6)/6+1;
prime5mod6 = (bool *) calloc(imax+1,sizeof(bool));
prime1mod6 = (bool *) calloc(imax+1,sizeof(bool));
sumprime=5;
for(i=1;(6*i-1)*(6*i-1)<=n;i++){
if(prime5mod6[i]==false){
sumprime=sumprime+6*i-1;
for(i1=6*i*i;i1 <= imax+2*i;i1+=(6*i-1)){
if(i1<=imax)
prime5mod6[i1]=true;
prime1mod6[i1-2*i]=true;
}
}
if(prime1mod6[i]==false){
sumprime=sumprime+6*i+1;
for(i1 = 6*i*i;i1<=imax;i1+=(6*i+1)){
prime5mod6[i1]=true;
if(i1<=imax-2*i)
prime1mod6[i1+2*i]=true;
}
}
}
for(i1=i;i1<=imax-1;i1++){
if(prime5mod6[i1]==false)
sumprime=sumprime+6*i1-1;
if(prime1mod6[i1]==false)
sumprime=sumprime+6*i1+1;
}
if(prime5mod6[imax]==false && n%6==5)
sumprime=sumprime+6*imax-1;
if(prime1mod6[imax-1]==false && n%6==0)
sumprime=sumprime-(6*(imax-1)+1);
printf("\nPrime sum: %ld",sumprime);
free(prime5mod6);
free(prime1mod6);
return 0;
}

Solving modulo equations programmatically

My goal is to implement a (simple) check digit alglorithm as described Here
My implemantion is the following but I am not sure if it is optimal:
private int CheckDigit(string SevenDecimal)
{
///Get UPC check digit of a 7-digit URI
///Add odd and multiply by 3 =Odds
///Add even =Evens
///Add Odds+Evens=sum
///Check digit is the number that makes Sum divisble by 10
int Odds = 0;
int Evens = 0;
int sum = 0;
int index = 0;
foreach (char digit in SevenDecimal)
{
index++;
int Digit = int.Parse(digit.ToString());
if (index % 2 == 0)
{
Evens +=Digit;
}
else
{
Odds +=Digit;
}
}
Odds = Odds * 3;
sum = Odds + Evens;
for (int i = 0; i < 10; i++) ///Brute force way check for better implementation
{
int Localsum;
Localsum = sum + i;
if (Localsum % 10 == 0)
{
return i;
}
}
return -1;//error;
}
My main concern is in the final for loop which as I describe is totallly brute.
Is there a better way to obtaining the check digit?
More precisely which is the best way to solve programmatically, the equation:
(sum+x)%10=0 //solve for x
To find "how much i you have to add to make the last digit of a number a 0", you can subtract from 10:
int checkDigit = (10 - (sum % 10)) % 10;
The second modulo is used for the special case when sum % 10 == 0, because 10 - 0 = 10
You are asking the wrong question. The expression is not one of equivalence thus x is not a value. The solution is that x is an infinite number of values each of which correctly solve the equation. As such you don't really want to solve for x but just check if x is in this solution space. You can check this simply with:
remainder = base - (sum % base)
You can then test if x sums up to the remainder with:
if (x % base === base - (sum % base))
{
// (sum + x) % base = 0 is true
}
Replace base with 10and you'll have it.

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

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