Project Euler 25 infinite loop - java

I'm working on the Project Euler 25. I worked out how to do Fibonacci and I'm using BigInteger. My program seems to be running for an infinite loop (or so I think). Could it be that it is taking a long time or is it actually going into infinite loop? Can someone point me in the correct direction so I can fix it?
import java.math.BigInteger;
public class Problem25 {
public static void main(String[] args) {
getTerm(0);
}
public static void getTerm(int start) {
BigInteger var = BigInteger.ZERO;
BigInteger var2 = BigInteger.valueOf(start);
int counter = 0;
while(true) {
BigInteger temp = var.add(var2);
var = var2;
var2 = temp;
counter++;
if(var.toString().length() > 1000) {
System.out.print(counter);
}
}
}
}
EDIT: Sorry people. I thought, I had break; but thanks for your responses.

You have no condition for terminating the loop:
while(true) { // << always true ;P
BigInteger temp = var.add(var2);
var = var2;
var2 = temp;
counter++;
if(var.toString().length() > 1000) {
System.out.print(counter);
}
}
So it is an infinite loop. You have two (or even more) options:
Specify in the while(statement) what is the condition to continue with the loop for another round.
Add some break; statement to stop the loop if a certain condition is evaluated as true.

getTerm(0);
Shouldn't this be getTerm(1);?
Also, MByD's answer is right; but this is also a critical problem. Without changing this, your program will never output.

1) Yes, you have an infinite loop. Put a break; statement right after your print().
2) Try looking for the first, oh, two-digit term. Or three-digit. Baby steps are good with a lot of the Project Euler problems.
3) Run it under a debugger, and watch what's happening. Combines well with 2).

You're calling getTerm(0), so initially var and var2 are both zero. Then you add var2 to var which is still zero, etc., so both var and var2 stay zero and you never make any progress. I think you meant getTerm(1), which should correctly generate the Fibonacci sequence.
And of course, you probably want to break out of the loop once you've found the answer.

Why don't you just print every value until a value with 1000 digits is found? There won't be that many anyway because the numbers grow with the golden ration on average.
And as stated elsewhere, add a stopcondition:
if(var.toString().length() > 1000) {
break;
}

Since true is always true, your loop will continue running forever unless you manually terminate it. Use break; for this. With your implementation, I think you should place it right after the line System.out.print(counter)

You can use:
while( !isGood() ) {
...
}
instead of
while(true) {
...
if ( isGood() ) {
break;
}
}
Here are 3 solutions that use the approach above (from slow to fast):
1) Generate all Fibonacci numbers until the condition is satisfied. Count the digits using division by 10. Time: 6625 ms
import java.math.BigInteger;
public class P25 {
final static int N = 1000;
public static void main(String[] args) {
int result = getTheFirstIndexHavingTheSpecifiedNumberOfDigits(N);
System.out.println(result);
}
// similar performance if you use an "aux" variable
private static int getTheFirstIndexHavingTheSpecifiedNumberOfDigits(int n) {
BigInteger a = BigInteger.ONE;
BigInteger b = BigInteger.ONE;
int i = 1;
while ( hasLessThanSpecifiedNumberOfDigits(a, n) ) {
b = b.add(a);
a = b.subtract(a);
i++;
}
return i;
}
private static boolean hasLessThanSpecifiedNumberOfDigits(BigInteger x, int n) {
return getNumberOfDigits(x) < n;
}
private static int getNumberOfDigits(BigInteger x) {
int numberOfDigits = 0 ;
while ( x.compareTo(BigInteger.ZERO) > 0 ) {
numberOfDigits++;
x = x.divide(BigInteger.TEN);
}
return numberOfDigits;
}
}
2) Generate all Fibonacci numbers until the condition is satisfied. Count the digits using the length of the string. Time: 783 ms
import java.math.BigInteger;
public class P25 {
final static int N = 1000;
public static void main(String[] args) {
int result = getTheFirstIndexHavingTheSpecifiedNumberOfDigits(N);
System.out.println(result);
}
private static int getTheFirstIndexHavingTheSpecifiedNumberOfDigits(int n) {
BigInteger a = BigInteger.ONE;
BigInteger b = BigInteger.ONE;
int i = 1;
while ( hasLessThanSpecifiedNumberOfDigits(a, n) ) {
b = b.add(a);
a = b.subtract(a);
i++;
}
return i;
}
private static boolean hasLessThanSpecifiedNumberOfDigits(BigInteger x, int n) {
return getNumberOfDigits(x) < n;
}
private static int getNumberOfDigits(BigInteger x) {
return x.toString().length();
}
}
3) Store the lowest BigInteger that has 1000 digits ( 10^999 ). Generate all Fibonacci numbers and compare them with the computed number. Time: 19 ms
import java.math.BigInteger;
public class P25 {
final static int N = 1000;
final static BigInteger MIN = BigInteger.TEN.pow(N-1);
public static void main(String[] args) {
int result = getTheFirstIndexHavingTheSpecifiedNumberOfDigits(N);
System.out.println(result);
}
private static int getTheFirstIndexHavingTheSpecifiedNumberOfDigits(int n) {
BigInteger a = BigInteger.ONE;
BigInteger b = BigInteger.ONE;
int i = 1;
while ( a.compareTo(MIN) < 0 ) {
b = b.add(a);
a = b.subtract(a);
i++;
}
return i;
}
}

Related

How can I turn this code from long into BigInteger

It is a code that gets prime numbers, I have made it as efficient as I could, but the problem is that I can't transform it to BigInteger, as long can't hold that much information; here the code:
public class p3{
static long perfectNumber;
static long mersenne;
public static void main(String[] args) {
long p = 2;
while (true) {
if( p % 2 == 0&&p!=2){
p++;
}
else{
if (isPrime(p) == true) {
mersenne = (long) (Math.pow(2, p) - 1);
if (isPrime(mersenne) == true) {
perfectNumber = (long) Math.pow(2, (p - 1)) * mersenne;
System.out.println(perfectNumber);
}
}
p+=1;
}
}
}
private static boolean isPrime(long testPrime) {
for (long i = 3; i < Math.sqrt(testPrime); i += 2) {
if (testPrime % i == 0) {
return false;
}
}
return true;
}
}
I've tried to use BigInteger but code is not working, as I can't use
BigInteger exponents with pow
You don't need to. The exponents don't need to be nearly as large as the mersenne primes and perfect numbers. They can have their own independent isPrime() test. In fact, they need to be int, instead of long, to satisfy BigInteger.pow().
Below is what you asked for, but may not be what you want. I doubt you'll get more then one additional perfect number beyond your original code due to time constraints which is why #WJS is pushing you in a different direction.
import java.math.BigInteger;
public class p3 {
static BigInteger TWO = new BigInteger("2");
static BigInteger THREE = new BigInteger("3");
public static void main(String[] args) {
int p = 2;
while (true) {
if (isPrime(p)) {
BigInteger mersenne = TWO.pow(p).subtract(BigInteger.ONE);
if (isPrime(mersenne)) {
System.out.println(TWO.pow(p - 1).multiply(mersenne));
}
}
p += (p == 2) ? 1 : 2;
}
}
private static boolean isPrime(BigInteger number) {
if (number.mod(TWO).equals(BigInteger.ZERO)) {
return number.equals(TWO);
}
for (BigInteger i = THREE; number.compareTo(i.multiply(i)) >= 0; i = i.add(TWO)) {
if (number.mod(i).equals(BigInteger.ZERO)) {
return false;
}
}
return true;
}
private static boolean isPrime(int number) {
if (number % 2 == 0) {
return number == 2;
}
for (int i = 3; number >= i * i; i += 2) {
if (number % i == 0) {
return false;
}
}
return true;
}
}
OUTPUT
> java p3
6
28
496
8128
33550336
8589869056
137438691328
2305843008139952128
2658455991569831744654692615953842176
Your original code outputs 0 in place of the final (37 digit) number above. So the immediate issue really is that long can't hold enough information. But beyond this point, you simply can't calculate fast enough with the above algorithm.
If we do something simple-minded to my above code, like replace this line:
if (isPrime(mersenne)) {
with:
if (mersenne.isProbablePrime(10)) {
The code will spit out the first 20 perfect numbers before slowing to a crawl. Tune the certainty argument of isProbablePrime() as you see fit.

Recursion in java, which one could be the best?

public class a1 {
private static int unit = 0;
private static int sum = 0;
public static void main(String[] foo) {
unit = 10;
System.out.println(tailRecur(unit));
System.out.println(tailRecur2(10));
}
public static int tailRecur(int result) {
int sum = result + unit - 1;
unit = unit - 1;
if (unit == 0) {
return sum;
}
return tailRecur(sum);
}
public static int tailRecur2(int unit) {
if (unit == 0) return sum;
sum = sum + unit;
return tailRecur2(unit - 1);
}
}
I wrote a simple method to get achieve 1+...+10. I am not sure which one could be better with the meaning of recursion syntax. The all give me the right answer.
Storing static variables is unnecessary, so either solution isn't ideal.
Try thinking like this
What are you trying to do? Answer: 1+...+N.
What is the input? Answer: N, the highest number to sum to.
What can you do in each step recursively that will help you reach your answer with that input? Answer: Take that number and add it to the result of all N - 1 solutions.
When should you stop recursion and start accumulating the summation results (what's your base case)? Answer: When the number hits 1 (generally, the smallest possible input), or even less than it to prevent a negative number input from causing a StackOverflow error.
public static int sumUpTo(int x) {
if (x <= 1) return x;
return x + sumUpTo(x - 1);
}

Trailing Zeroes of a Factorial

I'm trying to solve this coding question:
Given an integer n, return the number of trailing zeroes in n!
Below is my code (codec this up using the wiki link)
public int trailingZeroes(int n) {
int count = 0, i = 5;
while(i<=n){
count+= n/i;
i*=5;
}
return count;
}
This runs for all test cases except when n = Integer.MAX_VALUE upon which I get a TLE. How can I fix this code to make it cover that test case. I have read about five articles on the net and everything seems to agree with my approach.
Much thanks.
So, I followed the long/BigInteger approach (thanks y'all):
public int trailingZeroes(int n) {
long count = 0;
for(long i= 5; n/i >= 1; i= i*5){
count+= n/i;
}
return (int)count;
}
As Iaune observed, your loop will never terminate when n is Integer.MAX_VALUE, because there is no int greater than that number (by definition). You should be able to restructure your loop to avoid that problem. For instance, this is the same basic approach, but flipped upside-down:
public int trailingZeroes(int n) {
int count = 0;
while (n > 0) {
n /= 5;
count += n;
}
return count;
}
You cannot write a for or while loop where the loop counter is an int and the upper limit is <= Integer.MAX_VALUE.
What happens with a simple increment (counter++) is that the loop counter is set to that value, the body executes and then the counter is incremented which results in a negative number, Integer.MIN_VALUE. And then everything happens all over again.
Other weird things may happen when the loop counter is incremented in quantities > 1 or (as here) is multiplied: the int loop counter just can't hold a value > Integer.MAX_VALUE
Consider another approach for iterating over these numbers. Or handle MAX_VALUE separately.
Your problem is that once i gets large enough (more than Integer.MAX_INT / 5) then the line i*=5; causes i to overflow to the "wrong" value. The value in question is 5 to the 14th power, which is 6103515625, but which overflows to 1808548329.
The result of this is that the loop just keeps executing forever. i will never become a value that's not <= Integer.MAX_INT, because there's just no such int.
To avoid this, you need i to be a larger data type than an int. If you change i and count in your original code to long, this will work fine. Of course, BigInteger would also work.
public class FactorialNumberTrailingZeros {
public static void main(String[] args) {
System.out.println(trailingZeroes(1000020));
}
private static int trailingZeroes(int n) {
int count = 0;
while (n > 0 && (n % 10 == 0)) {
n /= 10;
count ++;
}
return count;
}
}
public static void main(String[] args) {
int result = findFactorialTrailingZero(100);
System.out.println("no of trailing zeros are " + result);
}
public static int findFactorialTrailingZero(int no) {
int zeros = no / 5;
int zeroIncrementNo = 25;
int zerosIncrementFactor = 1;
int nextZeroIncrenent = 5;
for (int i = 1;no >= zeroIncrementNo; i++) {
zeros=zeros+zerosIncrementFactor;
zeroIncrementNo=25*(i+1);
if(i+1==nextZeroIncrenent){
zerosIncrementFactor++;
nextZeroIncrenent=nextZeroIncrenent*5;
}
}
return zeros;
/*
[n/5]+[n/25]+[n/125]+....
if n<25 then [n/5]
if n<125 then [n/5]+[n/25]
if n<625 then [n/5]+[n/25]+[n/125]
*/
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
int countTrailingZeroes(int n)
{
int res=0;
for(int i=5;i<=n;i=i*5){
res=res+n/i;
}
return res;
}
int main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int n;
cin>>n;
cout<<countTrailingZeroes(n);
return 0;
}
Output
25
6
Explanation:
25!=1.551121e+25 i.e contains 6 trailing zeroes
Here is my python code that could solve your problem:
def check(n):
j,ans=5,0
while j<=n:
ans=ans+n//j
j=j*5
return ans

Java formula for if using

I have a code and I know that it isn't right. My task is "print all two-digit numbers which don't have two equal numbers". That means - program need to print numbers like 10, 12, 13 etc. Program didnt need to print 11 because there are 2 equal numbers. Hope that my program at least some is correct. (And sorry for my english).
public class k_darbs1 {
public static void main(String[] args) {
int a,b;
boolean notequal;
for(a = 10; a < 100; a++)
{
notequal = true;
for(b = 100; b < a; b++)
{
if(a != b)
{
notequal = false;
}
}
if(notequal == true)
{
System.out.println(a);
}
}
}
}
so why making things to much complex!?!!?!!!??
public static void main(String[] args) {
for(a = 10; a < 100; a++)
{
if(a%11==0){continue;}
System.out.println(a);
}
}
I think your making this slightly more complicated than it has to be. If n is a 2-digit number, then the leading digit is n/10 (integer division by 10) and the trailing digit is n%10 (modulo 10). You can just test if those two are unequal and print n as appropriate, there's no need for another for-loop.
For instance:
int n = 42;
System.out.println(n/10);
System.out.println(n%10);
4
2
Convert it to a string and check the characters.
for (int a = 10; a < 100; a++) {
String value = String.valueOf(a);
if (value.charAt(0) != value.charAt(1)) {
System.out.println(value);
}
}
You can parse Integer to String. Then compare the numbers with substring. For this process,
you need to know
Integer.toString(i);.
string.substring();
methods. This is not a very efficent way but it is a solution.

Using loops to compute factorial numbers, Java

I'm trying to compute the value of 7 factorial and display the answer, but when I tried to look up a way to do this I kept finding code that was written so that a number first had to be put in from the user and then it would factor whatever number the user put in. But I already know what number I need, obviously, so the code is going to be different and I'm having trouble figuring out how to do this.
I tried this at first
public class Ch4_Lab_7
{
public static void main(String[] args)
{
int factorial = 7;
while (factorial <= 7)
{
if (factorial > 0)
System.out.println(factorial*facto…
factorial--;
}
}
}
But all it does is display 7*7, then 6*6, then 5*5, and so on, and this isn't what I'm trying to do.
Does anyone know how to do it correctly?
import java.util.Scanner;
public class factorial {
public static void main (String[] args) {
Scanner input = new Scanner(System.in);
//Gives Prompt
System.out.print("Enter a number to find the factorial of it");
//Enter the times you want to run
int number = input.nextInt();
//Declares new int
int factor = 1;
//Runs loop and multiplies factor each time runned
for (int i=1; i<=number; i++) {
factor = factor*i;
}
//Prints out final number
System.out.println(factor);
}
}
Just keep multiplying it and until it reaches the number you inputted. Then print.
Input:5
Output:120
input:7
Output:5040
You need to have two variables, one for the factorial calculation and other for the purpose of counter. Try this, i have not tested it but should work:
public static void main(String[] args)
{
int input = 7;
int factorial = 1;
while (input > 0)
{
factorial = factorial * input
input--;
}
System.out.println("Factorial = " + factorial);
}
int a=7, fact=1, b=1;
do
{
fact=fact*b;//fact has the value 1 as constant and fact into b will be save in fact to multiply again.
System.out.print(fact);
b++;
}
while(a>=b); // a is greater and equals tob.
1st reason:
The methods you seen are probably recursive, which you seem to have edited.
2nd:
You are not storing, ANYWHERE the temporal results of factorial.
Try this
//number->n for n!
int number = 7;
//We'll store here the result of n!
int result = 1;
//we start from 7 and count backwards until 1
while (number > 0) {
//Multiply result and current number, and update result
result = number*result;
//Update the number, counting backwards here
number--;
}
//Print result in Screen
System.out.println(result);
Try this:
public static void main(String args[]) {
int i = 7;
int j = factorial(i); //Call the method
System.out.println(j); //Print result
}
public static int factorial(int i) { //Recursive method
if(i == 1)
return 1;
else
return i * factorial(i - 1);
}
This would print out the factorial of 7.
public class Factorial {
public static void main(String[] args) {
int result = factorial(5); //this is where we do 5!, to test.
System.out.println(result);
}
public static int factorial(int n) {
int x = 1;
int y = 1;
for (int i = 1; i <= n; i++) {
y = x * i;
x = y;
}
return y;
}
}
/*so, for 3! for example, we have:
i=1:
y = x * i, where x = 1, so that means:
y = 1*1 ; y= 1; x = y so x = 1. Then i increments =>
i = 2:
y = x * i. x is 1 and i is 2, so we have y = 2. Next step in code: x=y, means x = 2. Then i increments =>
i = 3:
y = x *i so we have y = 2*3. y=6. */

Categories

Resources