Sudden infinite loop above certain input argument? - java

While learning Java I'm redoing some of the Project Euler problems.
This is about Problem 14 - Longest Collatz sequence: https://projecteuler.net/problem=14
My programm runs just fine for a lower CEILING like 1000, but when executed like posted it loops infinitely, I think? What goes wrong here?
public class Test {
public static void main(String[] args) {
int tempMax = 0;
final int CEILING = 1_000_000;
for (int j = 1; j < CEILING; ++j) {
tempMax = Math.max(tempMax, collatzLength(j));
}
System.out.println(tempMax);
}
static int collatzLength(int n) { //computes length of collatz-sequence starting with n
int temp = n;
for (int length = 1; ; ++length) {
if (temp == 1)
return length;
else if (temp % 2 == 0)
temp /= 2;
else
temp = temp * 3 + 1;
}
}
}
Calling System.out.println(collatzLength(1000000)); seperately works just fine so I think we can rule an error here out.

You should use long instead of int. The int overflows while doing your calculations in collatzLength and that causes the infinite loop. From the problem description:
NOTE: Once the chain starts the terms are allowed to go above one million.
The number causing the problem: 113383
The long version gives a result, which is still incorrect because you are printing the length of the longest chain, but you need the number which produces the longest chain.
public static void main(String[] args)
{
int tempMax = 0;
final int CEILING = 1_000_000;
for (int j = 1; j < CEILING; ++j)
{
tempMax = Math.max(tempMax, collatzLength(j));
}
System.out.println(tempMax);
}
static int collatzLength(long n)
{
long temp = n;
for (int length = 1;; ++length)
{
if (temp == 1)
return length;
else if (temp % 2 == 0)
temp /= 2;
else
temp = temp * 3 + 1;
}
}

Related

how to find number with most divisor from array in java

I got some problem someone of with really helped me but I got program source code who print all of divisor from array, but I tried to print a number with most divisor for ex. array[1,2,3,4,5] and I want to print that the number with most divisor is 4 (1,2,4)
public static class Main {
public static void main(String[] args) {
System.out.println(getNumWithMaxDivisors(numbers));
}
static int getNumDivisors(int n) {
int noOfDivisors = 0;
for (int i = 1; i <= n / 2; i++) {
if (n % i == 0) {
System.out.print(i + " ");
noOfDivisors++;
}
}
return noOfDivisors;
}
static int getNumWithMaxDivisors(int[] numbers) {
int currentMaxDivisors = 0;
int numWithMaxDivisors = numbers[0];
for (int i = 0; i < numbers.length; i++) {
int numDivisors = getNumDivisors(numbers[i]);
if (numDivisors > currentMaxDivisors) {
numWithMaxDivisors = numbers[i];
}
}
return numWithMaxDivisors;
}
}
Code looks that, do you know where is a problem ?
The problem is that inside of your getNumWithMaxDivisors() method, you are not redefining the current number of max divisors. To fix this, you can update it inside of the if statement as so:
static int getNumWithMaxDivisors(int[] numbers) {
int currentMaxDivisors = 0;
int numWithMaxDivisors = numbers[0];
for (int i = 0; i < numbers.length; i++) {
int numDivisors = getNumDivisors(numbers[i]);
if (numDivisors > currentMaxDivisors) {
currentMaxDivisors = numDivisors; //ADD THIS LINE
numWithMaxDivisors = numbers[i];
}
}
return numWithMaxDivisors;
}
Input:
int[] numbers = {1,2,3,4,5};
System.out.println(getNumWithMaxDivisors(numbers));
Output:
4
Side Note: You could just as well start your for loop at i = 2 in your getNumDivisors() method, since every number is divisible by 1, so there is no point in checking it. This just saves you a bit of time!
add this line of code currentMaxDivisors = numDivisors; inside your if-statement like so:
static int getNumWithMaxDivisors(int[] numbers) {
int currentMaxDivisors = 0;
int numWithMaxDivisors = numbers[0];
for (int i = 0; i < numbers.length; i++) {
int numDivisors = getNumDivisors(numbers[i]);
if (numDivisors > currentMaxDivisors) {
currentMaxDivisors = numDivisors; //here this is missing
numWithMaxDivisors = numbers[i];
}
}
return numWithMaxDivisors;
}

Finding palindrome numbers

I'm trying to make a java code that displays the largest palindrome number made from the product of two 3-digit numbers. It outputs all palindromes, not in numerical order. I don't know why. Please help!
Here's my code:
`class Scratch {
public static void main(String[] args) {
int dig1, dig2, dig3, dig4, dig5, dig6, product;
for (int i =999; i>100; i--){
for (int j =999; j>=i;j--){
product = j*i;
dig1= product/100000;
dig2= (product/10000)%10;
dig3= (product/1000)%10;
dig4= (product/100)%10;
dig5= (product/10)%10;
dig6= (product%10);
if ((dig1==dig6) && (dig2==dig5) && (dig3==dig4)){
System.out.println((product));
break;
}
}
}
}}
A couple suggestions.
to avoid duplicate pairs, you can do this.
for (int i = 999; i > 100; i--) {
for (int k = i; k > 100; k--) {
To reverse the digits of a number, you can do it in a while loop.
Below, val is the product of i and j.
int rev = 0;
int temp = val;
while (temp != 0) {
rev = rev * 10 + temp % 10;
temp /= 10;
}
then
if (rev == val) { is a palindrome?
...
}
As each number is found, you can find the largest as follows. At the start,
initialize max to Integer.MIN_VALUE. Then do the following:
int savei = 0;
int savej = 0;
int max = Integer.MIN_VALUE;
// then later as you find the palindromes.
if (max < val) {
max = val;
savei = i
savej = j;
}
At the end, you will have the largest palindrome and the three digit numbers that divide it.

Java set/setElementAt not setting the right value

I need to find all the permutations for a given n(user input) without backtracking.
What i tried is:
import java.util.Scanner;
import java.util.Vector;
class Main {
private static int n;
private static Vector<Vector<Integer>> permutations = new Vector<>();
private static void get_n() {
Scanner user = new Scanner(System.in);
System.out.print("n = ");
n = user.nextInt();
}
private static void display(Vector<Vector<Integer>> permutations) {
for (int i = 0; i < factorial(n) - 1; ++i) {
for (int j = 0; j < n; ++j) {
System.out.print(permutations.elementAt(i).elementAt(j) + " ");
}
System.out.println();
}
}
private static int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; ++i) {
result *= i;
}
return result;
}
private static int max(Vector<Integer> permutation) {
int max = permutation.elementAt(0);
for (int i = 1; i < permutation.size(); ++i)
if (permutation.elementAt(i) > max)
max = permutation.elementAt(i);
return max;
}
// CHECKS FOR ELEMENT COUNT AND 0 - (n-1) APPARITION
public static int validate_permutation(Vector<Integer> permutation) {
// GOOD NUMBER OF ELEMENTS
if (max(permutation) != permutation.size() - 1)
return 0;
// PROPER ELEMENTS APPEAR
for (int i = 0; i < permutation.size(); ++i)
if (!permutation.contains(i))
return 0;
return 1;
}
private static Vector<Integer> next_permutation(Vector<Integer> permutation) {
int i;
do {
i = 1;
// INCREMENT LAST ELEMENT
permutation.set(permutation.size() - i, permutation.elementAt(permutation.size() - i) + 1);
// IN A P(n-1) PERMUTATION FOUND n. "OVERFLOW"
while (permutation.elementAt(permutation.size() - i) == permutation.size()) {
// RESET CURRENT POSITION
permutation.set(permutation.size() - i, 0);
// INCREMENT THE NEXT ONE
++i;
permutation.set(permutation.size() - i, permutation.elementAt(permutation.size() - i) + 1);
}
} while (validate_permutation(permutation) == 0);
// OUTPUT
System.out.print("output of next_permutation:\t\t");
for (int j = 0; j < permutation.size(); ++j)
System.out.print(permutation.elementAt(j) + " ");
System.out.println();
return permutation;
}
private static Vector<Vector<Integer>> permutations_of(int n) {
Vector<Vector<Integer>> permutations = new Vector<>();
// INITIALIZE PERMUTATION SET WITH 0
for (int i = 0; i < factorial(n); ++i) {
permutations.addElement(new Vector<>());
for(int j = 0; j < n; ++j)
permutations.elementAt(i).addElement(0);
}
for (int i = 0; i < n; ++i)
permutations.elementAt(0).set(i, i);
for (int i = 1; i < factorial(n); ++i) {
// ADD THE NEXT PERMUTATION TO THE SET
permutations.setElementAt(next_permutation(permutations.elementAt(i - 1)), i);
System.out.print("values set by permutations_of:\t");
for (int j = 0; j < permutations.elementAt(i).size(); ++j)
System.out.print(permutations.elementAt(i).elementAt(j) + " ");
System.out.println("\n");
}
System.out.print("\nFinal output of permutations_of:\n\n");
display(permutations);
return permutations;
}
public static void main(String[] args) {
get_n();
permutations.addAll(permutations_of(n));
}
}
Now, the problem is obvious when running the code. next_permutation outputs the correct permutations when called, the values are set correctly to the corresponding the vector of permutations, but the end result is a mass copy of the last permutation, which leads me to believe that every time a new permutation is outputted by next_permutation and set into the permutations vector, somehow that permutation is also copied over all of the other permutations. And I can't figure out why for the life of me.
I tried both set, setElementAt, and an implementation where I don't initialize the permutations vector fist, but add the permutations as they are outputted by next_permutation with add() and I hit the exact same problem. Is there some weird way in which Java handles memory? Or what would be the cause of this?
Thank you in advance!
permutations.setElementAt(next_permutation(permutations.elementAt(i - 1)), i);
This is literally setting the vector at permutations(i) to be the same object as permutations[i-1]. Not the same value - the exact same object. I think this the source of your problems. You instead need to copy the values in the vector.

Function takes a martix (2d array) and prints the max number of the even numbers in each line

I am defining a function to accept a matrix (2d array), for example x[][]; and the function should print the biggest even number in each line
public static void biggestEvenNumOfEachLine(int x[][]){
int even,t=0,max;
int arr[] = new int [x.length];
for(int i = 0; i < x.length;i++){
for(int j = 0; j < x[i].length;j++,t++){
if(x[i][j] % 2 == 0){
even = x[i][j];
arr[j] = even;
}
}
}
}
What am I missing?
I would start by finding the biggest even number in a single line array. Start with the smallest possible value, and then iterate the array. Test for even, and then set the max (and then return it). Something like,
private static int biggestEvenNum(int[] x) {
int max = Integer.MIN_VALUE;
for (int i = 0; i < x.length; i++) {
if (x[i] % 2 == 0) {
max = Math.max(max, x[i]);
}
}
return max;
}
But, in Java 8+, I would prefer to filter for even values and get the max like
private static int biggestEvenNum(int[] x) {
return IntStream.of(x).filter(v -> v % 2 == 0).max().getAsInt();
}
Then your method is as simple as iterating the line(s) in your matrix, printing the result. Like,
public static void biggestEvenNumOfEachLine(int[][] x) {
for (int[] line : x) {
System.out.println(biggestEvenNum(line));
}
}
public static void biggestEvenNumOfEachLine(int x[][])
{
int arr[] = new int [x.length];
for(int i = 0; i < x.length;i++)
for(int j = 0; j < x[i].length;j++)
if(x[i][j] % 2 == 0 && x[i][j] > arr[i]){
arr[i] = x[i][j];
System.out.println(arr[i]);
}
}
This will work but if there is no even number at particular line then corresponding number to that line will be zero.

Calculate factorial of 50 using array only in java

I'm a total beginner of java.
I have a homework to write a complete program that calculates the factorial of 50 using array.
I can't use any method like biginteger.
I can only use array because my professor wants us to understand the logic behind, I guess...
However, he didn't really teach us the detail of array, so I'm really confused here.
Basically, I'm trying to divide the big number and put it into array slot. So if the first array gets 235, I can divide it and extract the number and put it into one array slot. Then, put the remain next array slot. And repeat the process until I get the result (which is factorial of 50, and it's a huge number..)
I tried to understand what's the logic behind, but I really can't figure it out.. So far I have this on my mind.
import java.util.Scanner;
class Factorial
{
public static void main(String[] args)
{
int n;
Scanner kb = new Scanner(System.in);
System.out.println("Enter n");
n = kb.nextInt();
System.out.println(n +"! = " + fact(n));
}
public static int fact(int n)
{
int product = 1;
int[] a = new int[100];
a[0] = 1;
for (int j = 2; j < a.length; j++)
{
for(; n >= 1; n--)
{
product = product * n;
a[j-1] = n;
a[j] = a[j]/10;
a[j+1] = a[j]%10;
}
}
return product;
}
}
But it doesn't show me the factorial of 50.
it shows me 0 as the result, so apparently, it's not working.
I'm trying to use one method (fact()), but I'm not sure that's the right way to do.
My professor mentioned about using operator / and % to assign the number to the next slot of array repeatedly.
So I'm trying to use that for this homework.
Does anyone have an idea for this homework?
Please help me!
And sorry for the confusing instruction... I'm confused also, so please forgive me.
FYI: factorial of 50 is 30414093201713378043612608166064768844377641568960512000000000000
Try this.
static int[] fact(int n) {
int[] r = new int[100];
r[0] = 1;
for (int i = 1; i <= n; ++i) {
int carry = 0;
for (int j = 0; j < r.length; ++j) {
int x = r[j] * i + carry;
r[j] = x % 10;
carry = x / 10;
}
}
return r;
}
and
int[] result = fact(50);
int i = result.length - 1;
while (i > 0 && result[i] == 0)
--i;
while (i >= 0)
System.out.print(result[i--]);
System.out.println();
// -> 30414093201713378043612608166064768844377641568960512000000000000
Her's my result:
50 factorial - 30414093201713378043612608166064768844377641568960512000000000000
And here's the code. I hard coded an array of 100 digits. When printing, I skip the leading zeroes.
public class FactorialArray {
public static void main(String[] args) {
int n = 50;
System.out.print(n + " factorial - ");
int[] result = factorial(n);
boolean firstDigit = false;
for (int digit : result) {
if (digit > 0) {
firstDigit = true;
}
if (firstDigit) {
System.out.print(digit);
}
}
System.out.println();
}
private static int[] factorial(int n) {
int[] r = new int[100];
r[r.length - 1] = 1;
for (int i = 1; i <= n; i++) {
int carry = 0;
for (int j = r.length - 1; j >= 0; j--) {
int x = r[j] * i + carry;
r[j] = x % 10;
carry = x / 10;
}
}
return r;
}
}
How about:
public static BigInteger p(int numOfAllPerson) {
if (numOfAllPerson < 0) {
throw new IllegalArgumentException();
}
if (numOfAllPerson == 0) {
return BigInteger.ONE;
}
BigInteger retBigInt = BigInteger.ONE;
for (; numOfAllPerson > 0; numOfAllPerson--) {
retBigInt = retBigInt.multiply(BigInteger.valueOf(numOfAllPerson));
}
return retBigInt;
}
Please recall basic level of math how multiplication works?
2344
X 34
= (2344*4)*10^0 + (2344*3)*10^1 = ans
2344
X334
= (2344*4)*10^0 + (2344*3)*10^1 + (2344*3)*10^2= ans
So for m digits X n digits you need n list of string array.
Each time you multiply each digits with m. and store it.
After each step you will append 0,1,2,n-1 trailing zero(s) to that string.
Finally, sum all of n listed string. You know how to do that.
So up to this you know m*n
now it is very easy to compute 1*..........*49*50.
how about:
int[] arrayOfFifty = new int[50];
//populate the array with 1 to 50
for(int i = 1; i < 51; i++){
arrayOfFifty[i-1] = i;
}
//perform the factorial
long result = 1;
for(int i = 0; i < arrayOfFifty.length; i++){
result = arrayOfFifty[i] * result;
}
Did not test this. No idea how big the number is and if it would cause error due to the size of the number.
Updated. arrays use ".length" to measure the size.
I now updated result to long data type and it returns the following - which is obviously incorrect. This is a massive number and I'm not sure what your professor is trying to get at.
-3258495067890909184

Categories