First find out how many numbers you can keep in memory. In this example, suppose you can store 999 numbers.
Your first step will be to pre-calculate the digit products for all numbers from 0 to 999 and store them in memory. So, you will have an array line by line:
multLookup = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, ...]
Now you add your number to a bunch of three-digit numbers. For example, if your number is 1739203423 , you divide it into 1 , 739 , 203 and 423 . You will look at each of them in your multLookup array and multLookup results together like this:
solution = multLookup[1] * multLookup[739] * multLookup[203] * multLookup[423];
With this approach, you will accelerate the calculations by 3 times (since we selected 999 elements for storage in memory). To speed it up by 5, store 99999 numbers in memory and follow the same steps. In your case, an acceleration of 5 means that you will come to your decision in 29.2 seconds .
Note: The gain is not exactly linear with respect to the number of numbers that you store in memory. See Jogojapan's reasoning in the comments on this question why this is so.
If you know more about the order in which your numbers are displayed, or about the range of your numbers (for example, your input is only in the range [0, 10000]), you can make this algorithm more intelligent.
In your example, you use a for loop to iterate from 0 to 1,000,000,000. In this case, this approach will be super-efficient, because the memory will not often occur due to a page error, and there will be less cache misses.
But wait! You can do it even faster (for your specific iteration example for a loop)! How, you ask? Caching! Suppose you have passed ten-digit numbers.
Let's say you start with 8934236000 . Based on 999 digits in the memory solution, you divide this into 8 , 934 , 236 and 000 . Then you will multiply:
solution = multLookup[8] * multLookup[934] * multLookup[236] * multLookup[0];
Then you take 8934236001 , split it into 8 , 934 , 236 and 001 and multiply:
solution = multLookup[8] * multLookup[934] * multLookup[236] * multLookup[1];
And so on ... But we notice that the first three searches are the same for the next 997 iterations! So, we cache this.
cache = multLookup[8] * multLookup[934] * multLookup[236];
And then we use the cache as such:
for (int i = 0; i < 1000; i++) { solution = cache * i; }
And just like that, we almost reduced the time by 4 times. So you take the 29.2 second decision you had and divide it by 4 to go through all the billions of numbers in ~ 7.3 seconds