0

I want to apply the Collatz Sequence and apply it to all numbers from 1 to 10^6, and return the number with the largest chain needed to reach 1. However, I have the problem that my loops dont seem to terminate in Eclipse and I can't figure out why, I can't even get all my prints shown in the console despite wanting it out every step.

The collatz sequence is is computed by the following rules:

  • if n is odd, the next number is n/2

  • if n is even, the next number is 3n + 1

This is what I have so far:

public static long collatz() {

    long res = 0;
    long n = 1;
    long count = 0;
    long largestCount = 0;
    long t = 0;

    for (long k = 1; k <= 20; k++) {

        n = k;

        while (n != 1) {

            if ((n % 2) == 0) {
                n = n / 2;
                count = count + 1;
            }

            else {
                n = (3 * n) + 1;
                count = count + 1;

            }

            if (count > largestCount) {
                largestCount = count;
                res = k;
            }
        }
    }

    System.out.println(res);
    return res;

}
Cat Tran
  • 3
  • 3
  • Did you wait long enough? I changed `k <= 1000000` to `k <= 20` and this program exited. – MikeCAT May 01 '16 at 07:46
  • this should execute normally. the fact that you are printing a bunch of stuff is causing the delay – Debosmit Ray May 01 '16 at 07:48
  • The printing will be 264,868,848 lines + 1 (the "result:" line) according to [this simulation](http://ideone.com/1XoAg4). Why do you want so many lines? – MikeCAT May 01 '16 at 07:51
  • Thank you for your answers. I removed the prints and changed k to k<=20, however, it still doesnt run. – Cat Tran May 01 '16 at 08:10

4 Answers4

0

Your code should run properly. It is not working code though. You are checking the condition to see if the current count is greater than the present largest count inside the while loop, which does not really make sense, since you need to get the length of the collatz sequence and then compare it to the current maximum. Other than that, your code is good. :)

This is something I had written up, if you are interested.

final int number = 1000000;

long sequenceLength = 0;
long startingNumber = 0;
long sequence;

for (int i = 2; i <= number; i++) {
    int length = 1;
    sequence = i;
    while (sequence != 1) {
        if ((sequence % 2) == 0) {
            sequence = sequence / 2;
        } else {
            sequence = sequence * 3 + 1;
        }
        length++;
    }

    //Check if sequence is the best solution
    if (length > sequenceLength) {
        sequenceLength = length;
        startingNumber = i;
    }
}
System.out.println(startingNumber);
Debosmit Ray
  • 5,228
  • 2
  • 27
  • 43
  • thank you for your answer, but can you explain the difference in your code to mine? it looks the same to me, except for the prints I had in mine. – Cat Tran May 01 '16 at 08:22
  • @CatTran Of course! You were checking the condition to see if the current `count` is greater than the present largest count **inside** the while loop, which does not really make sense, since you need to get the length of the collatz sequence and then, check it's size. Otherwise, your code is good. :) – Debosmit Ray May 01 '16 at 08:45
  • @CatTran It would be nice, if you could accept/upvote an answer if your issue is resolved, or close to a resolution. From [here](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work), "Accepting an answer is important as it both rewards posters for solving your problem and informs others that your issue is resolved." – Debosmit Ray May 01 '16 at 08:47
  • Ah okay, I got it. Thank you again. I'm sorry about not accepting, this is my first post on stackoverflow. – Cat Tran May 01 '16 at 08:59
0

It runs but it will always print the last tested number, since you do not reset the count.

I've also moved the increment of the count value out of the if/else statement, since the incrementing does not depend on the value of n.

And I've moved the update of largestCount after the while loop.

public static long collatz() {

    long res = 0;
    long n = 1;
    long count = 0;
    long largestCount = 0;
    long t = 0;

    for (long k = 1; k <= 20; k++) {

        n = k;
        count = 0; // start every sequence with count = 0

        while (n != 1) {

            if ((n % 2) == 0) {
                n = n / 2;
            }
            else {
                n = (3 * n) + 1;
            }
            count = count + 1;
        }
        if (count > largestCount) {
            largestCount = count;
            res = k;
        }
    }

    System.out.println(res);
    return res;
}
Thomas Kläger
  • 17,754
  • 3
  • 23
  • 34
0

If you read my solution, you can see how writing comments for what a bunch of code lines are supposed to do is very useful and makes the code self-documented..

Try Online

public static long collatz(int maxN)
{
    long res = 0, n = 1, count = 0, largestCount = 0, t = 0;

    // for K in [1, max-N]
    for (long k = 1; k <= maxN; k++)
    {
        // reset count to zero
        n = k; count = 0;

        // count how many steps to get to 1
        while (n != 1)
        {
            // n = collatz(n)
            n = (n%2==0 ? n/2 : (3*n)+1);

            count++; // count the step
        }

        // check for maximum count
        if (count > largestCount)
        {
            largestCount = count;
            res = k;
        }
    }

    return res; // return maximum solution
}
Khaled.K
  • 5,828
  • 1
  • 33
  • 51
0

Use Biginteger instead of Long in C# or Visual basic

e.g. http://herbert-helling.de/VB_Tests/

User9123
  • 91
  • 1
  • 2