How can I make ProjectEuler 23 Solution faster - java

This is what I have. It is solving the problem, but taking forever. Can I divide the last loop 0 to 28123 into half and run them simultaneously somehow to make it faster, and then in the end add the two sums to get the final result? Will "thread" help? What can I do to make the code solve faster?
/*
A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.
A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.
As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.
Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.
*/
public class power {
public static void main(String[] args){
System.out.println(bigSum());
}
public static boolean isPerfect(int a){
boolean perfect = false;
int sum = 0;
for(int i = 1; i<(a/2)+1; i++)
{
if (a%i == 0)
{
sum = sum + i;
}
}
if(a == sum){
perfect = true;
}
return perfect;
}
public static boolean isAbundant(int a){
boolean Abundant = false;
int sum = 0;
for(int i = 1; i<(a/2)+1; i++)
{
if (a%i == 0)
{
sum = sum + i;
}
}
if(a < sum){
Abundant = true;
}
return Abundant;
}
public static boolean isDeficient(int a){
boolean Deficient = false;
int sum = 0;
for(int i = 1; i<(a/2)+1; i++)
{
if (a%i == 0)
{
sum = sum + i;
}
}
if(a > sum){
Deficient = true;
}
return Deficient;
}
public static boolean isSumOfTwoAbundant(int a){
boolean SumOfTwoAbundant = false;
for(int i = 1; i<a; i++){
if(isAbundant(i) && isAbundant(a-i)){
SumOfTwoAbundant = true;
}
}
return SumOfTwoAbundant;
}
public static long bigSum(){
int sum = 0;
for(int i = 0; i<28123; i++){
if(!isSumOfTwoAbundant(i)){
sum = sum + i;
System.out.println("i: " + i + "; " + "Sum: " + sum);
}
}
return sum;
}
}

You're recomputing whether every number < a is abundant with every call of isSumOfTwoAbundant. Try keeping a list of abundant numbers and add to it when you find one. Then you can loop through that list rather than rechecking for abundance for numbers < a. Something like:
public static boolean isSumOfTwoAbundant(int a){
boolean SumOfTwoAbundant = false;
if(isAbundant(a))
{
abundants.add(a);
}
for(int i = 0; i<abundants.length; i++) {
for(int j = 0; j < abundants.length; j++) {
if(a - abundants[i] == abundants[j]){
SumOfTwoAbundant = true;
}
}
}
return SumOfTwoAbundant ;
}
private ArrayList<int> abundants;
There are a lot of other ways to make this better, too, but Project Euler is about learning those through experience.

Another Java solution: (takes less than a second)
static int sum_Of_Divisors(int n){
int limit = n;
int sum = 0;
for(int i=1;i<limit;i++){
if(n%i==0){
if(i!=1){
if(i != n/i) sum += (i + n/i);
else sum += i;
}
else
sum += i;
limit = n/i;
}
}
return sum;
}
static boolean isAbundant(int n){
int sum = sum_Of_Divisors(n);
return sum>n;
}
static boolean sum_of_Two_Abundant(int n, HashSet<Integer> abundant){
for(Integer i:abundant){
if(abundant.contains(n-i)) return true;
}
return false;
}
static long q23(){
long sum = 0;
HashSet<Integer> abundant = new HashSet<Integer>();
for(int i=2;i<=28123;i++){
if(isAbundant(i))
abundant.add(i);
}
for(int i=1;i<=28123;i++)
if(!sum_of_Two_Abundant(i, abundant)) sum+=i;
return sum;
}

Related

Finding the smith number between given range

I will get to the point quickly. Basically smith numbers are: Composite number the sum of whose digits is the sum of the digits of its prime factors (excluding 1). (The primes are excluded since they trivially satisfy this condition). One example of a Smith number is the beast number 666=2·3·3·37, since 6+6+6=2+3+3+(3+7)=18.
what i've tried:
In a for loop first i get the sum of the current number's(i) digits
In same loop i try to get the sum of the number's prime factors digits.
I've made another method to check if current number that is going to proccessed in for loop is prime or not,if its prime it will be excluded
But my code is seems to not working can you guys help out?
public static void main(String[] args) {
smithInrange(1, 50);
}
public static void smithInrange(int start_val, int end_val) {
for (int i = start_val; i < end_val; i++) {
if(!isPrime(i)) { //since we banned prime numbers from this process i don't include them
int for_digit_sum = i, digit = 0, digit_sum = 0, for_factor_purpose = i, smith_sum = 0;
int first = 0, second = 0, last = 0;
// System.out.println("current number is" + i);
while (for_digit_sum > 0) { // in this while loop i get the sum of current number's digits
digit = for_digit_sum % 10;
digit_sum += digit;
for_digit_sum /= 10;
}
// System.out.println("digit sum is"+digit_sum);
while (for_factor_purpose % 2 == 0) { // i divide the current number to 2 until it became an odd number
first += 2;
for_factor_purpose /= 2;
}
// System.out.println("the first sum is " + first);
for (int j = 3; j < Math.sqrt(for_factor_purpose); j += 2) {
while (for_factor_purpose % j == 0) { // this while loop is for getting the digit sum of every prime
// factor that j has
int inner_digit = 0, inner_temp = j, inner_digit_sum = 0;
while (inner_temp > 0) {
inner_digit = inner_temp % 10;
second += inner_digit;
inner_temp /= 10;
}
// System.out.println("the second sum is " + second);
for_factor_purpose /= j;
}
}
int last_temp = for_factor_purpose, last_digit = 0, last_digit_sum = 0;
if (for_factor_purpose > 2) {
while (last_temp > 0) {
last_digit = last_temp % 10;
last += last_digit;
last_temp /= 10;
}
// System.out.println("last is " + last);
}
smith_sum = first + second + last;
// System.out.println("smith num is "+ smith_sum);
// System.out.println(smith_sum);
if (smith_sum == digit_sum) {
System.out.println("the num founded is" + i);
}
}
}
}
public static boolean isPrime(int i) {
int sqrt = (int) Math.sqrt(i) + 1;
for (int k = 2; k < sqrt; k++) {
if (i % k == 0) {
// number is perfectly divisible - no prime
return false;
}
}
return true;
}
the output is:
the num founded is4
the num founded is9
the num founded is22
the num founded is25
the num founded is27
the num founded is49
how ever the smith number between this range(1 and 50) are:
4, 22 and 27
edit:I_ve found the problem which is :
Math.sqrt(for_factor_purpose) it seems i should add 1 to it to eliminate square numbers. Thanks to you guys i've see sthe solution on other perspectives.
Keep coding!
Main loop for printing Smith numbers.
for (int i = 3; i < 10000; i++) {
if (isSmith(i)) {
System.out.println(i + " is a Smith number.");
}
}
The test method to determine if the supplied number is a Smith number. The list of primes is only increased if the last prime is smaller in magnitude than the number under test.
static boolean isSmith(int v) {
int sum = 0;
int save = v;
int lastPrime = primes.get(primes.size() - 1);
if (lastPrime < v) {
genPrimes(v);
}
outer:
for (int p : primes) {
while (save > 1) {
if (save % p != 0) {
continue outer;
}
sum += sumOfDigits(p);
save /= p;
}
break;
}
return sum == sumOfDigits(v) && !primes.contains(v);
}
Helper method to sum the digits of a number.
static int sumOfDigits(int i) {
return String.valueOf(i).chars().map(c -> c - '0').sum();
}
And the prime generator. It uses the list as it is created to determine if a given
number is a prime.
static List<Integer> primes = new ArrayList<>(List.of(2, 3));
static void genPrimes(int max) {
int next = primes.get(primes.size() - 1);
outer:
while (next <= max) {
next += 2;
for (int p : primes) {
if (next % p == 0) {
continue outer;
}
if (p * p > next) {
break;
}
}
primes.add(next);
}
}
}
I do not want to spoil the answer finding, but just some simpler code snippets,
making everything simpler, and more readable.
public boolean isSmith(int a) {
if (a < 2) return false;
int factor = findDivisor(a);
if (factor == a) return false;
int sum = digitSum(a);
// loop:
a /= factor;
sum -= digitSum(factor);
...
}
boolean isPrime(int a){
for(int i = 2; i*i <= a; i++) {
if (a % i == 0) {
return false;
}
}
return true;
}
int findDivisor(int a){
for(int i = 2; i*i <= a; i++) {
if (a % i == 0) {
return i;
}
}
return a;
}
int digitSum(int a) {
if (a < 10) {
return a;
}
int digit = a % 10;
int rest = a / 10;
return digit + digitSum(rest);
}
As you see integer division 23 / 10 == 2, and modulo (remainder) %: 23 % 10 == 3 can simplify things.
Instead of isPrime, finding factor(s) is more logical. In fact the best solution is not using findDivisor, but immediately find all factors
int factorsSum = 0;
int factorsCount = 0;
for(int i = 2; i*i <= a; i++) {
while (a % i == 0) {
factorsSum += digitSum(i);
a /= i;
factorsCount++;
}
}
// The remaining factor >= sqrt(original a) must be a prime.
// (It cannot contain smaller factors.)
factorsSum += digitSum(a);
factorsCount++;
Here is the code. If you need further help, please let me know. The code is pretty self explanatory and a decent bit was taken from your code but if you need me to explain it let me know.
In short, I created methods to check if a number is a smith number and then checked each int in the range.
import java.util.*;
public class MyClass {
public static void main(String args[]) {
System.out.println(smithInRange)
}
public int factor;
public boolean smithInRange(int a, int b){
for (int i=Math.min(a,b);i<=Math.max(a,b);i++) if(isSmith(i)) return true;
return false;
}
public boolean isSmith(int a){
if(a<2) return false;
if(isPrime(a)) return false;
int digits=0;
int factors=0;
String x=a+¨" ";
for(int i=0;i<x.length()-1;i++) digits+= Integer.parseInt(x.substring(i,i+1));
ArrayList<Integer> pF = new ArrayList<Integer>();
pF.add(a);
while(!aIsPrime(pF)){
int num = pF.get(pF.size-1)
pF.remove(pF.size()-1);
pF.add(factor);
pF.add(num/factor)
}
for(int i: pF){
if((factors+"").length()==1)factors+= i;
else{
String ss= i+" ";
int nums=0;
for(int j=0;j<ss.length()-1;j++){
nums+=Integer.parseInt(ss.substring(j,j+1));
}
}
}
return (factors==digits);
}
public boolean isPrime(int a){
for(int i=2;i<=(int)Math.sqrt(a),i++){
String s = (double)a/(double)i+"";
if(s.substring(s.length()-2).equals(".0")){
return false;
factor = i;
}
}
return true;
}
public boolean aIsPrime(ArrayList<int> a){
for(int i: a) if (!isPrime(a)) return false;
return true;
}
}

Program that displays every perfect number

My code runs but for one of the tests two outputs are printed when I only need one. I am unsure of how to avoid this.
This is the task:
Write an application that displays every perfect number from 2 through 1,000. A perfect number is one that equals the sum of all the numbers that divide evenly into it. For example, 6 is perfect because 1, 2, and 3 divide evenly into it and their sum is 6; however, 12 is not a perfect number because 1, 2, 3, 4, and 6 divide evenly into it, and their sum is greater than 12.
The provided template lays out the initial for loop to check each number beginning from 2 and going up to 1,000. In this for loop, the perfect() method is called, where you will submit your piece of code to test if each number follows the conditions described above.
Set result to true if it meets those conditions and use sum to add up the numbers divisible by int n in the method's parameter.
public class Perfect{
public static void main (String args[]){
final int MAX = 1000;
for(int i = 2; i <= MAX; i++)
if(perfect(i) == true)
System.out.println("The number " + i + " is perfect");
}
public static boolean perfect(int n){
int sum = 1;
int i;
boolean result = false;
for (i = 2; i < n / 2; i++) {
if (n % i == 0) {
sum += i;
}
}
if (sum == i) {
return true;
}
else {
return false;
}
}
}
My output:
The number 496 is perfect
The number 729 is perfect
Expected output:
The number 496 is perfect
It only expects the first line printed...
You need to compare sum to the original number n, not to i. And you need to add 1 to the loop condition or it will miss the last divider in even numbers
public static boolean perfect(int n){
int sum = 1;
for (int i = 2; i < (n / 2) + 1; i++) {
if (n % i == 0) {
sum += i;
}
}
return sum == n;
}
First, I don't know if you have used the correct formula. But, you should know that the first perfect number are 6, 28, 496 and 8128. 729 is not a perfect number.
Hope it helped.
public static void main(String[] args) {
int i, j, s;
System.out.println("Perfect numbers 1 to 1000: ");
for(i=1;i<=1000;i++){
s=0;
for(j=1;j<i;j++){
if(i%j==0){
s=s+j;
}
}
if(i==s){ //if i == s is perfect
System.out.println(i);
}
}
}
}
According to the question, you have to print all perfect numbers.
I have created a small snippet, try it and see.
public void printPerfect() {
for(int i=2;i<1000;i++) {
List<Integer> l =factors(i);
int sum =0;
for (Integer factor : l) {
sum+=factor;
}
if(sum==i) {
System.out.println("perfect-- " +i);
}
}
}
List<Integer> factors(int number) {
List<Integer> l = new ArrayList<Integer>();
for(int i = 1; i <= number; ++i) {
if (number % i == 0) {
if(i!=number)
l.add(i);
}
}
return l;
}
You checked sum == i instead of sum == n.
As 729 = 3^6 : 3, 243, 9, 81, 27.
public static boolean perfect(int n) {
int sum = 1;
for (int i = 2; i <= n / 2 && sum <= n; i++) {
if (n % i == 0) {
sum += i;
}
}
return sum == n;
}

Error in calculating sum of even place digits and odd place digits in java

In our directions, we have to get a 16 digit number, then sum all the digits in the odd place from right to left. After that, we have to sum all the even place digits from right to left, double the sum, then take module 9. When I try to run my code, I keep getting "Invalid", even if it is with a valid credit card number.
public static boolean validateCreditCard(long number) {
double cardSum = 0;
for (int i = 0; i < 16; i++) {
long cardnumber = (long) Math.pow(10, i);
double oddPlaceSum = 0;
double evenPlaceSum = 0;
if (i % 2 != 0) {
oddPlaceSum += ((int)(number % cardnumber / (Math.pow(10, i))));
} else { // so if i%2 ==0
evenPlaceSum += ((int)(number % cardnumber / (Math.pow(10, i)) * 2 % 9));
}
cardSum += evenPlaceSum + oddPlaceSum;
}
if (cardSum % 10 == 0) {
return true;
System.out.println("Valid");
} else {
return false;
System.out.println("Invalid");
}
}
Try this instead :
Convert the 16 digit number into a String using Long.toString(number).
Iterate through the String character by character and keep track of even and odd indexes.
Convert each char to an Integer using Integer.valueOf() thereby adding them incrementally.
Voila, you got your evenSum and oddSum. Next steps should be trivial.
public static boolean validateCreditCard(long number){
String x = Long.toString(number);
int evenSum = 0;
int oddSum = 0;
for(int i=0; i<x.length; i=i+2) {
oddSum += Integer.valueOf(s[i]);
evenSum += Integer.valueOf(s[i+1]);
}
//Do the next steps with odd and even sums.
Also, do handle IndexOutOfBoundsException as appropriate.
You can do it in a single while loop as digits are fixed, like this:
int digit,evensum,oddsum;
int i=16;
while(i > 0){
digit=number%10;
if(i%2 == 0)
evensum+=digit;
else
oddsum+=digit;
i--;
digit/=10;
}
Try this instead
using Recusion find sum of even placed of digit and sum of odd placed of digit.
class Recursion {
static int count = 0;
static int even =0;
static int odd =0;
public static int Digits(int num) {
if (num > 0) {
count++;
if(count%2 == 0){
even += num%10;
}
else{
odd += num%10;
}
Digits(num / 10);
}
return even;
// for odd
// return odd;
}
public static void main(String[] args) {
int num = 31593;
int res = Digits(num);
System.out.println("Total digits are: " + res);
}
}
Help me How to print both even and odd sum together?

Prime numbers in a given range with less complexity

I have used below programs to find first n prime numbers (in below program it is from 2 to n). Can we write a program with single for loop? I also tried recursive approach but it is not working for me.
public static void main(String[] args) {
// Prime numbers in a range
int range = 15;
int num = 1;
int count = 0;
boolean prime = true;
while (count < range) {
num = num + 1;
prime = true;
for (int i = 2; i <= num / 2; i++) {
if (num % i == 0) {
prime = false;
break;
}
}
if (prime) {
count++;
System.out.println(num);
}
}
}
i dont think you can reduce it to one loop. But you can improve your code as Luca mentioned it.
public class PrimeFinder {
private final List<Integer> primes;
private final int primeCapacity;
public PrimeFinder(final int primeCapacity) {
if (primeCapacity < 3) {
throw new IllegalArgumentException("Tkat is way to easy.");
}
this.primeCapacity = primeCapacity;
primes = new ArrayList<>(primeCapacity);
primes.add(2);
}
public void find() {
final Index currentNumber = new Index();
while (primes.size() < primeCapacity) {
if (!primes.stream().parallel().anyMatch(prime -> (currentNumber.value % prime) == 0)) {
primes.add(currentNumber.incremet());
} else {
currentNumber.incremet();
}
}
}
public List<Integer> getPrimes() {
return primes;
}
private class Index {
public int value = 3;
public int incremet() {
return value++;
}
}
public static void main(String[] args) {
PrimeFinder primeFinder = new PrimeFinder(100000);
final long start = System.currentTimeMillis();
primeFinder.find();
final long finish = System.currentTimeMillis();
System.out.println("Score after " + (finish - start) + " milis.");
primeFinder.getPrimes().stream().forEach((prime) -> {
System.out.println(prime);
});
}
}
main rule here is simple, if given number isnt clearly divided by any prime number that you already have found, then it is prime number.
P.S. dont forget that primes.strem().... is loop also, so it is not a one loop code.
P.S.S. you can reduce this much further.
to understand the complexity of your algorithm you don't have to count the number of inner loops but the number of times you are iterating over your elements. To improve the performance of your algorithm you need to investigate if there are some iterations that could be unnecessary.
In your case when you do
for (int i = 2; i <= num / 2; i++) you are testing your num against values that are not necessary.. ex: if a number is divisible by 4 it will be by 2 too.
when you do for (int i = 2; i <= num / 2; i++) with num = 11
i will assume the values 2,3,4,5. 4 here is a not interesting number and represent an iteration that could be avoided.
anyway according to wikipedia the sieve of Eratosthenes is one of the most efficient ways to find all of the smaller primes.
public class PrimeSieve {
public static void main(String[] args) {
int N = Integer.parseInt(args[0]);
// initially assume all integers are prime
boolean[] isPrime = new boolean[N + 1];
for (int i = 2; i <= N; i++) {
isPrime[i] = true;
}
// mark non-primes <= N using Sieve of Eratosthenes
for (int i = 2; i*i <= N; i++) {
// if i is prime, then mark multiples of i as nonprime
// suffices to consider mutiples i, i+1, ..., N/i
if (isPrime[i]) {
for (int j = i; i*j <= N; j++) {
isPrime[i*j] = false;
}
}
}
// count primes
int primes = 0;
for (int i = 2; i <= N; i++) {
if (isPrime[i]) primes++;
}
System.out.println("The number of primes <= " + N + " is " + primes);
}
}
I don't know any way use a single loop for your question, but I do see two places where you can reduce the complexity:
Cache the prime numbers you found and use these prime numbers to decide if a number is prime or not. For example, to decide if 11 is a prime number, you just need to divide it by 2,3,5,7 instead of 2,3,4,5,6,...10
You don't need to check till num/2, you only need to check till the square root of num. For example, for 10, you only need to check 2,3 instead of 2,3,4,5. Because if number n is not prime, then n = a * b where either a or b is smaller than the square root x of n). If a is the smaller one, knowing that n can be divided by a is enough to decide that n is not prime.
So combining 1 & 2, you can improve the efficiency of your loops:
public static void main(String[] args) {
// Prime numbers in a range
int range = 15;
int num = 1;
int count = 0;
boolean prime = true;
ArrayList<Integer> primes = new ArrayList<>(range);
while (num < range) {
num = num + 1;
prime = true;
int numSquareRoot = (int) Math.floor(Math.pow(num, 0.5));
for (Integer smallPrimes : primes) {// only need to divide by the primes smaller than num
if (numSquareRoot > numSquareRoot) {// only need to check till the square root of num
break;
}
if (num % smallPrimes == 0) {
prime = false;
break;
}
}
if (prime) {
System.out.println(num);
primes.add(num);// cache the primes
}
}
}

Largest prime factor program takes aaaages - Java

So this is problem 3 from project Euler. For those who don't know, I have to find out the largest prime factor of 600851475143. I have the below code:
import java.lang.Math;
// 600851475143
public class LargestPrimeFactor {
public static void main(String[] stuff) {
long num = getLong("What number do you want to analyse? ");
long[] primes = primeGenerator(num);
long result = 0;
for(int i = 0; i < primes.length; i++) {
boolean modulo2 = num % primes[i] == 0;
if(modulo2) {
result = primes[i];
}
}
System.out.println(result);
}
public static long[] primeGenerator(long limit) {
int aindex = 0;
long[] ps = new long[primeCount(limit)];
for(long i = 2; i < limit + 1; i++) {
if(primeCheck(i)) {
ps[aindex] = i;
aindex++;
}
}
return ps;
}
public static boolean primeCheck(long num) {
boolean r = false;
if(num == 2 || num == 3) {
return true;
}
else if(num == 1) {
return false;
}
for(long i = 2; i < Math.sqrt(num); i++) {
boolean modulo = num % i == 0;
if(modulo) {
r = false;
break;
}
else if(Math.sqrt(num) < i + 1 && !modulo) {
r = true;
break;
}
}
return r;
}
public static int primeCount(long limit) {
int count = 0;
if(limit == 1 || limit == 2) {
return 0;
}
for(long i = 2; i <= limit; i++) {
if(primeCheck(i)) {
count++;
}
}
return count;
}
public static long getLong(String prompt) {
System.out.print(prompt + " ");
long mrlong = input.nextLong();
input.nextLine();
return mrlong;
}
}
But when I test the program with something (a lot) smaller than 600851475143, like 100000000, then the program takes its time - in fact, 100000000 has taken 20 minutes so far and is still going. I've obviously got the wrong approach here (and yes, the program does work, I tried it out with smaller numbers). Can anyone suggest a less exhaustive way?
public static void main(String[] args) {
long number = 600851475143L;
long highestPrime = -1;
for (long i = 2; i <= number; ++i) {
if (number % i == 0) {
highestPrime = i;
number /= i;
--i;
}
}
System.out.println(highestPrime);
}
public class LargestPrimeFactor {
public static boolean isPrime(long num){
int count = 0;
for(long i = 1; i<=num/2 ; i++){
if(num % i==0){
count++;
}
}
if(count==1){
return true;
}
return false;
}
public static String largestPrimeFactor(long num){
String factor = "none";
for(long i = 2; i<= num/2 ; i++){
if(num % i==0 && isPrime(i)){
factor = Long.toString(i);
}
}
return factor;
}
public static void main(String[] args) {
System.out.println(largestPrimeFactor(13195));
}
}
I have done several dozen of the challenges on Project Euler. Some of the questions can be solved with brute force (they recommend not to do this) but others require "out of the box" thinking. You cannot solve that by problem with brute force.
There is lots of help on the web to lead you in the right direction, for example:
http://thetaoishere.blogspot.com.au/2008/05/largest-prime-factor-of-number.html
The number of prime factors a number can have is always less than sqrt of that number so that there is no need to iterate through the number n to find its largest prime factor.
See this code.
public class LargestPrimeFactor {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
long num=sc.nextLong();
if(num>0 && num<=2)
{
System.out.println("largest prime is:-" + num);
System.exit(0);
}
int i=((Double)Math.sqrt(num)).intValue();
int j=3;
int x=0;
//used for looping through the j value which can also be a prime. for e.g in case of 100 we might get 9 as a divisor. we need to make sure divisor is also a prime number.
int z=0;
//same function as j but for divisor
int y=3;
int max=2;
//divisor is divisible
boolean flag=false;
//we found prime factors
boolean found=false;
while(x<=i)
{
y=3;
flag=false;
if(num % j ==0)
{
if(j>max)
{
for(z=0;z<Math.sqrt(j);z++)
{
if(j!=y && j % y==0)
{
flag=true;
}
y+=2;
}
if(!flag)
{
found=true;
max=j;
}
}
}
j+=2;
x++;
}
if(found){
System.out.println("The maximum prime is :- " + max);
}
else
{
System.out.println("The maximum prime is :- " + num);
}
}
}
change
for(long i = 2; i <= limit; i++)
to
// add the one for rounding errors in the sqrt function
new_limit = sqrt(limit) + 1;
// all even numbers are not prime
for(long i = 3; i <= new_limit; i+=2)
{
...
}
Factoring 1,000,000 for example instead of iterating 1,000,000 times
the thing only needs to do around 500 iterations.

Categories