2

I was solving Project Euler problems and I'm stuck at number 14, I did manage to solve it using brute force, the problem states: http://projecteuler.net/problem=14

The following iterative sequence is defined for the set of positive integers:

   n → n/2 (n is even)
   n → 3n + 1 (n is odd)

Using the rule above and starting with 13, we generate the following sequence:

   13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1

It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.

Which starting number, under one million, produces the longest chain?

NOTE: Once the chain starts the terms are allowed to go above one million.

What I want to do is to implement a cache, I want to use an integer array as the cache, the index will be the number and the count stored in each cell will be the length of the chain, when we hit a number for which the cache cell already has a positive number we skip further checking(break the loop), fetch the existing counter data from the loop and add it to the current counter value, and start from the next number, so here's the implementation:

Working brute force code removed due to Project Euler policy, down below is the faulty code.

public class Challenge14 {

public static void main(String[] args) {
    
    int[] collatzCache=new int[1000000]; //cache
    
    int count=0;
    long maxCount=0;
    int maxNumber=0;
    long number;
    
    int limit=1000000;
    
    for(int i=0;i<limit;i++)
    {
        int counter=0;
        number=i;
        while(number>1)
        {
            if(number%2==0)
            {
                number=number/2;
            }
            else 
            {
                number=3*number+1;
            }

            if(number<limit && collatzCache[(int)number]>0) //check
            {
                counter=collatzCache[(int) number];
                break;
            }
            counter++;
        }
        count=counter+1;
        collatzCache[i]=count;
    if(count>maxCount)
    {
        maxCount=count;
        maxNumber=i;
    }
    }
    System.out.println(maxNumber);


}
}

But it's not working, where am I going wrong here? Is it due to the long to int typecasting?

Community
  • 1
  • 1
skynil
  • 23
  • 5
  • Project Euler explicitly asks people not to post solutions online. – Software Engineer Jan 12 '14 at 18:41
  • I'll delete the working solution then, but I do need help with the cache. Edit: Sorry for asking noob question, where is the edit button for questions? – skynil Jan 12 '14 at 19:15
  • Brute force answers to PE questions, especially the early ones, are just a google search away. I don't think there's much to be gained by deleting your brute force solution here, but if you need to edit a post, the "edit" link is below the tags, which are below the question itself. – lreeder Jan 12 '14 at 19:44
  • I don't need help with Brute Force, with modern computers processing power almost all the pre 2005 questions can be solved easily, but I try to find a solution that will run on even the slowest machines, not depending on processing power or advanced libraries. – skynil Jan 12 '14 at 19:56

1 Answers1

2

At this line:

counter=collatzCache[(int) number];

you overwrite what was in counter with the cache value and so lose the extra chain steps.

Jackson
  • 5,627
  • 2
  • 29
  • 48
  • What Jackson said. You're dropping the current length of the chain and replacing it with the cache value. You need to add what's in the cache to the counter for the full chain length. – lreeder Jan 12 '14 at 20:44
  • Yes, that's it, thanks a lot, I made a very bad mistake, god knows how I will deal with the more complex problems later on if I keep making mistakes like these. And to ireeder's previous comment the cache helped immensely here: **Without cache: 540ms** **With cache: 40ms** That's a near **12 times** speedup, this will help immensely if I were to feed it say 10 million numbers or more. – skynil Jan 13 '14 at 17:58