Division By Zero Error For Project Euler? - java

I am trying to solve some project Euler problems and for whatever reason the following code gives me a division by zero error whenever I try to run it with large numbers. Can anyone tell me why?
import java.util.Scanner;
public class Problem3LargestPrimeFactor {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Please enter the number to find the largest prime factor for.");
long num = input.nextLong();
int largest = 1;
boolean isPrime = true;
for(int i = 2; i < num; i++) {
if(num % i == 0) {
for(int u = 2; u < i; u++){
if(i % u == 0)
isPrime = false;
}
if(isPrime)
largest = i;
}
}
}
}
Now I'm aware that this is not the most efficient way to design the algorithm but can anyone tell me what is going on here?

You're overflowing int. In the loop for(int i = 2; i < num; i++), num is a long and i is only an int. When i reaches it's capacity, it wraps around to -2,147,483,648 and keeps being incremented until it gets to 0, at which point you get your error.

Other responses have already pointed out your error. Let me give you a better algorithm for factoring a composite integer using trial division. The basic idea is to simply iterate through the possible factors, reducing n each time you find one. Here's pseudocode:
function factors(n)
f, fs := 2, {}
while f * f <= n
while n % f == 0
append f to fs
n := n / f
f := f + 1
if n > 1
append n to fs
return fs
If you're interested in programming with prime numbers, I modestly recommend this essay at my blog.

Related

Trying to write a program for Highest common factor of two numbers. But the output is showing the initialized value that is 1

The output is not showing the HCF but showing the initialized value that is 1.
package questionsOnLoops;
import java.util.Scanner;
public class hg {
public static void main(String[] args) {
Scanner srv = new Scanner(System.in);
System.out.print("Enter the first number: ");
int n1 = srv.nextInt(); //first number
System.out.println("Enter the second number: ");
int n2 = srv.nextInt(); //second number
int HCF=1; // Highest Common factor
int s; //smaller of two number
s = Math.min(n1, n2);
for(int i = s; i <= 1 ; i--) {
if(n1%i==0&&n2%i==0) {
HCF=i;
break;
}
}
System.out.println(HCF);
}
}
for(i = 1; i <= a || i <= b; i++) {
if( a%i == 0 && b%i == 0 )
hcf = i;
}
Use this logic. here a is the first number and b is the second.
Your code is never executing the "for" loop because you set i=s and i will never be i<=1...
Change to i>=1 and you're good to go
You have just to change your operator in your 'for' loop.
for(int i = s; i >= 1 ; i--) {
Because in your code you loop while i is less than 1. But in your inizialization i is equal to s. So you never enter in the 'for' loop and your HCF is the default value of your HCF variable which is 1.
For your culture if you want an optimized way to calculate the HCF, you can use the Euclidean algorithm which reduce drastically the number of operation. Because you transform several division and condition into a few Euclidean division.
Here an exemple
public int hcf(int m, int n) {
// the remainder of the Euclidean division
int r = 0;
// The algorithm says "the HCF of m and n is the last non-zero remainder"
while(n != 0) {
r = m % n;
m = n;
n = r;
}
return m;
}

Terminated due to timeout error in java code in hackerrank program

Problem(Hackerrank)
Given a base-10 integer, n, convert it to binary (base-2). Then find and print the base-10 integer denoting the maximum number of consecutive 1's in n's binary representation.
My Code is given below; which shows "RuntimeError"- and the compiler message is "Terminated due to timeout".
import java.util.*;
public class Solution {
public static void main(String[] args) {
Scanner scn = new Scanner(System.in);
int n=scn.nextInt();
int rem = 0,s = 0,t = 0;
while (n > 0)
rem = n % 2;
n = n / 2;
if (rem == 1)
{
s++;
if (s >= t)
t = s;
else
s = 0;
}
System.out.println(t);
scn.close();
}
}
Could you please help me to fix this error?
while (n > 0)
rem = n % 2;
n = n / 2;
Here, n = n / 2 is outside the loop, so n will never change and this will be an infinite loop. That's why you get the timeout.
Change it to:
while (n > 0) {
rem = n % 2;
n = n / 2;
}
Hint: Always use braces. They'll ensure that multiple instructions are part of the if/while/whatever block and improve readability on single-instruction blocks.

Decrease execution time of the Java program

I wrote the following program for the second problem of project Euler, for the question: "Project Euler #3: Largest prime factor".It is supposed to print out all the highest prime factors of the provided inputs.
import java.util.Scanner;
public class euler_2 {
public static boolean isPrime(int n) {
if (n % 2 == 0) return false;
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0)
return false;
}
return true;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
for (int i = 0; i < a; i++) {
int b = sc.nextInt();
for (int j = b; j >= 1; j--) {
boolean aa = isPrime(j);
if (aa == true && b % j == 0) {
b = j;
break;
}
}
System.out.println(b);
}
}
}
What changes can I make to the program to make it execute faster? What would be a better algorithm for this problem?
The problem with your approach is that for every number N, you try each number smaller or equal to N whether it is a prime and after that whether it is a divisor of N.
Obvious improvement is to check whether it is a divisor first and only then whether it is a prime. But most probably this will not help that much.
What you can do instead is just to start checking each number whether it is a divisor of a number. If it is a divisor, divide it. You continue this till sqrt(N).
I have not done anything with java in a long time, but here is Go implementation, which most probably any Java person will be able to transform to Java.
func biggestPrime(n uint64) uint64 {
p, i := uint64(1), uint64(0)
for i = 2; i < uint64(math.Sqrt(float64(n))) + uint64(1); i++ {
for n % i == 0 {
n /= i
p = i
}
}
if n > 1 {
p = n
}
return p
}
Using my algorithm it will take you O(sqrt(N)) to find the biggest prime of a number. In your case it was O(N * sqrt(N))
Attempt to factor the number into 2 factors. Repeat on the largest factor found so far until you find one that can't be factored -- that is the largest prime factor.
There are many different ways you might try to factor the numbers, but since they are only ints, then Fermat's method or even trial division (going down from sqrt(N)) will probably do. See http://mathworld.wolfram.com/FermatsFactorizationMethod.html

program logic of printing the prime numbers

Can any body help to understand this java program?
It just prints prime numbers, as you enter how many you want and it works well.
class PrimeNumbers
{
public static void main(String args[])
{
int n, status = 1, num = 3;
Scanner in = new Scanner(System.in);
System.out.println("Enter the number of prime numbers you want");
n = in.nextInt();
if (n >= 1)
{
System.out.println("First "+n+" prime numbers are :-");
System.out.println(2);
}
for ( int count = 2 ; count <=n ; )
{
for ( int j = 2 ; j <= Math.sqrt(num) ; j++ )
{
if ( num%j == 0 )
{
status = 0;
break;
}
}
if ( status != 0 )
{
System.out.println(num);
count++;
}
status = 1;
num++;
}
}
}
I don't understand this for loop condition
for ( int j = 2 ; j <= Math.sqrt(num) ; j++ )
why we are taking sqrt of num...which is 3....why we assumed it as 3?
Imagine that n can be divided by a number k that is greater than sqrt(n). Then you have:
n = k * j
where j is a number which must be less than sqrt(n) (if both k and j are greater than sqrt(n) then their product would be greater than n).
So you only need to find the divisors that are less than or equals to sqrt(n) and you can find those that are greater than or equals to sqrt(n) by a simple division. In my example, once you have found j, you can find k = n / j.
The line in question is basically trying to find numbers that are factors of your given number (and eliminating them as not-primes). If you find no factors of a given number then you can say that the number is prime.
As far as finding factors goes, you only need to go up to sqrt(N) because if you go any higher you are looking at numbers you have already seen before. This is because every time you find a factor you actually find two factors. If a is a factor of N then N/a and a are both factors of N.
A number N is prime if the only integers that satisfy N = A*B are 1 and N (or N and 1).
Now to check a number N as prime we could search all A from 2 to N and B from 2 to N, to see if N=A*B. That would take O(N^2) time, and is really inefficient.
It turns out that we only need to divide N by a number and see if there is a remainder. This brings it down to O(N).
And further, we don't need to check all the way from A=2 to A=N. If A is greater than sqrt(N), then B must be less than sqrt(N). Therefore we only need to check A from 2 to sqrt(N) to see if N/A has a remainder.
If I'm right there is a theory in math, saying that nearly all prime numbers can be determined when checking numbers from 2 to square root of n instead of checking all numbers from 2 to n oder 2 to n/2.
The factor of a number can lie only from 1 to sqrt of num. So instead of checking from 1 till num for its factors, we check for all numbers from 1 to sqrt(num) so see if any of them divides num. If any divides num, it is not prime, else it is. This improves efficiency of code.
A quick but dirty solution..
import java.util.Scanner;
class testing
{
public static void main(String args[])
{
Scanner input = new Scanner(System.in);
int n, i, j, count = 1;
System.out.print("How many Numbers ? : ");
n = input.nextInt();
for(j = 1;count<=n;j++)
{
if(j==1 || j==2)
{
System.out.println(j);
count++;
continue;
}
for(i=2;i<=j/2;i++)
{
if(j%i==0)
break;
else if(i == j/2 && j%i != 0)
{
System.out.println(j);
count++;
}
}
}
}
}
public class PrimeNumber {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList a = new ArrayList();
for (int i = 1; i <= 100; ++i) {
if (isPrime(i))
a.add(i);
}
System.out.println("List : " + a);
}
public static boolean isPrime(int value) {
if (value <= 1)
return false;
if ((value % 2) == 0)
return (value == 2);
for (int i = 3; i <= value - 1; i++) {
if (value % i == 0) {
return false;
}
}
return true;
}
}

Reversing an integer in Java using a for loop

This is a homework problem
How would I reverse an integer in Java with a for loop? The user will input the integer (I don't know how long it will be) and I need to reverse it. ie: If they enter 12345, my program returns 54321.
Here's the catch, you can't use String, StringBuffer, arrays, or other advanced structures in this problem.
I have a basic idea of what I need to do. My problem is...in the for loop, wouldn't the condition need to be x < the length of the integer (number of digits)? How would I do that without String?
Thanks for any input, and I'll add more information if requested.
EDIT:
Of course, after introspection, I realized I should use another for loop to do this. What I did was create a for loop that will count the digits by dividing by 10:
int input = scan.nextInt();
int n = input;
int a = 0;
for (int x = 0; n > 0; x++){
n = n/10;
a = a + 1;
}
EDIT 2:
This is what I have
int input = scan.nextInt();
int n = input;
int a = 0;
int r = 0;
for (int x = 0; n > 0; x++){
n = n/10;
a = a + 1;
}
for (int y = 0; y < n; y++) {
r = r + input%10;
input = input/10;
}
System.out.println(input);
When I run it, it isn't reversing it, it's only giving me back the numbers. ie: if I put in 1234, it returns 1234. This doesn't make any sense to me, because I'm adding the last digit to of the input to r, so why wouldn't it be 4321?
While your original number is nonzero, take your result, multiply it by 10, and add the remainder from dividing the original by 10.
For example, say your original number is 12345. Start with a result of 0.
Multiply result by 10 and add 5, giving you 5. (original is now 1234.)
Multiply result by 10 and add 4, giving you 54. (original is now 123.)
Multiply result by 10 and add 3, giving you 543. (original = 12.)
Multiply result blah blah 5432. (original = 1.)
Multiply, add, bam. 54321. And 1 / 10, in int math, is zero. We're done.
Your mission, should you choose to accept it, is to implement this in Java. :) (Hint: division and remainder are separate operations in Java. % is the remainder operator, and / is the division operator. Take the remainder separately, then divide the original by 10.)
You will need to use math to access each of the digits. Here's a few hints to get your started:
Use the % mod operator to extract the last digit of the number.
Use the / division operator to remove the last digit of the number.
Stop your loop when you have no more digits in the number.
This might not be the proper way but
public static int reverseMe(int i){
int output;
String ri = i + "";
char[] inputArray = ri.toCharArray();
char[] outputArray = new char[inputArray.length];
for(int m=0;m<inputArray.length;m++){
outputArray[inputArray.length-m-1]=inputArray[m];
}
String result = new String(outputArray);
output = Integer.parseInt(result);
return output;
}
public static void reverse2(int n){
int a;
for(int i = 0; i < n ; i ++){
a = n % 10;
System.out.print(a);
n = n / 10;
if( n < 10){
System.out.print(n);
n = 0;
}
}
}
here is the Answer With Correction of Your Code.
import static java.lang.Math.pow;
import java.util.*;
public class MyClass {
public static void main(String args[]) {
Scanner scan=new Scanner(System.in);
int input = scan.nextInt();
int n = input;
int a = 0;
int r = 0;
for (; n > 0;){
n = n/10;
a = a + 1;
}
for (int y = 0; y < input;a--) {
r =(int)( r + input%10*pow(10,a-1));
input = input/10;
}
System.out.println(r);
}
}

Categories