views:

1286

answers:

13

Write a program to print out all possible values of int data type from the smallest to the largest, using Java.

Some notable solutions as of 8th of May 2009, 10:44 GMT:

1) Daniel Lew was the first to post correctly working code.

2) Kris has provided the simplest solution for the given problem.

3) Tom Hawtin - tackline, came up arguably with the most elegant solution.

4) mmyers pointed out that printing is likely to become a bottleneck and can be improved through buffering.

5) Jay's brute force approach is notable since, besides defying the core point of programming, the resulting source code takes about 128 GB and will blow compiler limits.

As a side note I believe that the answers do demonstrate that it could be a good interview question, as long as the emphasis is not on the ability to remember trivia about the data type overflow and its implications (that can be easily spotted during unit testing), or the way of obtaining MAX and MIN limits (can easily be looked up in the documentation) but rather on the analysis of various ways of dealing with the problem.

+2  A: 

The maximum value for int is Integer.MAX_VALUE and the minimum is Integer.MIN_VALUE. Use a loop to print all of them.

cd1
That's 2 English sentences, not a Java program. :-)
Ken
+14  A: 
class Test {
    public static void main(String[] args) {
        for (int a = Integer.MIN_VALUE; a < Integer.MAX_VALUE; a++) {
            System.out.println(a);
        }
        System.out.println(Integer.MAX_VALUE);
    }
}

Am I hired?

Daniel Lew
I wouldn't, ;) just because you have an extra line for no reason whatsoever. Why not just:for (int a = Integer.MIN_VALUE; a <= Integer.MAX_VALUE; a++) { System.out.println(a); }
Matthew Flaschen
No, you didn't comment your code :)
Valerion
If you don't add that last line, your loop will never terminate. Using your method, when a == Integer.MAX_VALUE, you'll print it, increment a, and suddenly a will be Integer.MIN_VALUE.
Daniel Lew
Matthew Flaschen, you have fallen victim to one of the classic blunders
Bobby Eickhoff
@Daniel-an if condition could be inside the for loop to see if max value is a after print and if so break;
TStamper
So you'd add an extra conditional check to every single iteration, instead of just printing the max value at the end? And you think that's an improvement?
Chad Birch
@Chad Birch- true it is an extra condition, but it would look better..lol
TStamper
do-while would be my choice.
Tom Hawtin - tackline
I believe Matthew has illustrated why this might be a good interview question...
Kris
@Kris +1; if something looks that simple on the surface, it HAS to be a trick.
Adam Jaskiewicz
Daniel, not hired yet, not that easilly anyway. But look at all the reputation you've just earned. :-)
Totophil
Good question? Well, If I never run and tested the code I wrote, then I might have missed the infinite loop... Relevant. not really.
KarlP
Yecch, -1, use a long.
Dave
@Dave: Why would I change my answer when Kris has already used that exact method? It's helpful to no one if everyone edits their answers to be the same thing, especially when both of our answers are valid.Besides, my solution is easily translatable into "print all values of long", whereas a version that uses long would have to move to BigInt to use the same solution (and would consequently be a lot slower).
Daniel Lew
+4  A: 

Is there something tricky that I'm not catching? There probably is... (edit: yes, there is!)

class AllInts {
    public static void main(String[] args) {
        // wrong -- i <= Integer.MAX_VALUE will never be false, since
        // incrementing Integer.MAX_VALUE overflows to Integer.MIN_VALUE.
        for (int i = Integer.MIN_VALUE; i <= Integer.MAX_VALUE; i++) {
            System.out.println(i);
        }
    }
}

Since the printing is the bottleneck, a buffer would improve the speed quite a lot (I know because I just tried it):

class AllInts {
    public static void main(String[] args) {
        // a rather large cache; I did no calculations to optimize the cache
        // size, but adding the first group of numbers will make the buffer
        // as large as it will ever need to be.
        StringBuilder buffer = new StringBuilder(10000000);
        int counter = 0;
        // note that termination check is now <
        // this means Integer.MAX_VALUE won't be printed in the loop
        for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
            buffer.append(i).append('\n');
            if (++counter > 5000000) {
                System.out.print(buffer);
                buffer.delete(0, buffer.length()-1);
                counter = 0;
            }
        }
        // take care of the last value (also means we don't have to check
        // if the buffer is empty before printing it)
        buffer.append(Integer.MAX_VALUE);
        System.out.println(buffer);
    }
}

Also, this version will actually terminate (thanks to Daniel Lew for pointing out that there was, in fact, something tricky that I wasn't catching).

The total run time for this version (run with -Xmx512m) was 1:53. That's over 600000 numbers/second; not bad at all! But I suspect that it would have been slower if I hadn't run it minimized.

Michael Myers
Your loop will never terminate.
Daniel Lew
Java is subject to integer overflow, and so when i == Integer.MAX_VALUE, it will be incremented by one and overflow into Integer.MIN_VALUE
Daniel Lew
I'm in two minds whether to give that an up vote...
Tom Hawtin - tackline
Ah, there *was* something tricky. I thought it was merely for performance that you use a < instead of a <=. (And my second version is a lot faster than yours, if it matters. ;)
Michael Myers
Well, it prints faster, but it sure doesn't finish earlier. ;)
Daniel Lew
The second version (with a bigger buffer, actually) took about two and a half hours to complete. And it does stop at 2147483647 like it should.
Michael Myers
+1  A: 

Package fj is from here.

import static fj.pre.Show.intShow;
import static fj.pre.Show.unlineShow;
import static fj.data.Stream.range;
import static java.lang.Integer.MIN_VALUE;
import static java.lang.Integer.MAX_VALUE;

public class ShowInts
  {public static void main(final String[] args)
     {unlineShow(intShow).println(range(MIN_VALUE, MAX_VALUE + 1L));}}
Apocalisp
Way too much work, and includes additional libraries.
cdeszaq
http://en.wikipedia.org/wiki/Not_Invented_Here
Apocalisp
Sure, but why would you add an additional dependency for something as trivial as this?
Simon Nickerson
A: 

At 1000 lines/sec you'll be done in about 7 weeks. Should we get coffee now?

Steve B.
That's not a problem. it should produce output faster than you can read it. Have fun.
Tom Hawtin - tackline
Actually, it's closer to 10000 lines/sec (at least with buffering). That's about 5 days. :D
Michael Myers
Actual time was about 2 1/2 hours with buffered output. That's more like 4 or 500000 lines/sec. Maybe it was faster because it was minimized.
Michael Myers
+15  A: 

Simplest form (minimum code):

    for (long i = Integer.MIN_VALUE; i <= Integer.MAX_VALUE; i++) {
        System.out.println(i);
    }

No integer overflow, no extra checks (just a little more memory usage, but who doesn't have 32 spare bits lying around).

While I suppose

    for (long i = Integer.MIN_VALUE; i <= Integer.MAX_VALUE; i++)
        System.out.println(i);

has fewer characters, I can't really say that it is simpler. Shorter isn't necessarily simpler, it does have less code though.

Kris
Will never terminate (see previous answers).
Michael Myers
that's an infinite loop
TStamper
Nicely done. 32 bits is nothing, especially on a 64bit architecture where, depending on the VM, you would just waste more memory.
cdeszaq
/me needs to learn to read. Sorry, my internet connection is crazy slow today and it's driving me to distraction. Please ignore me while I spout nonsense. :)
Michael Myers
You totally dont need those carriage returns or curly braces!
Karl
How would that loop forever? A long will not overflow with Integer.MAX_VALUE + 1. Its a long, not an int.
cdeszaq
Very creative..
Kibbee
But do you really want long? (I really want arbitrary bit integers, but that's another question.)
Tom Hawtin - tackline
Another curveball - With "server" VM, it will actually terminate in the middle. There is a HotSpot bug that will convert 'i <= Integer.MAX_INT' ( which may require two comparison '<' and '=' ) into 'i < Integer.MAX_INT + 1'. Because it will overflow and turn into negative number, the loop will just terminate. However, this is not the case -client mode.
mjlee
Excellent point by mjlee
matt b
A: 

Just improving the StringBuilder's approach a little:

2 threads + 2 buffers (i.e. StringBuilder): The main idea is that one thread fills one buffer while the other thread dumps the content of the other buffer.

Obviously, the "dumper" thread will always run slower than the "filler" thread.

ATorras
What happens when you run out of memory? Pause the "filler" thread?
Michael Myers
Out Of Memory? I have not specified the size of the buffers, the -Xms parameters... I think that 2 buffers with chars 16bit wide, some internal gaps and buffers... I hope that `new StringBuilder(15*1024*1024)` is a safe choice for a 64MB (default?) VM without having OOMs.
ATorras
+8  A: 

I just have to add an answer...

public class PrintInts {
    public static void main(String[] args) {
        int i = Integer.MIN_VALUE;
        do {
            System.out.println(i);
            ++i;
        } while (i != Integer.MIN_VALUE);
    }
}
  • We don't want the body repeated (think of the maintenance!)
  • It doesn't loop forever.
  • It uses an appropriate type for the counter.
  • It doesn't require some wild third-party weirdo library.
Tom Hawtin - tackline
+3  A: 

When I first looked at this, my first question was 'how do you define smallest and largest'. For what I thought was the most obvious definition ('smallest' == 'closest to 0') the answer would be

for (int i = 0; i >= 0; i++) {
    System.out.println(i);
    System.out.println(-i-1);
}

But everyone else seems to read 'smallest' as 'minimum' and 'largest' as 'maximum'

Chris Dodd
I read the question the same way. Integer.MIN_VALUE is not a small number, it is a very large negative number.
Dave Sherohman
+3  A: 

Come on folks, it said using java. It didn't say use an int in the for loop. :-)

public class Silly {
  public static void main(String[] args) {
    for (long x = Integer.MIN_VALUE; x <= Integer.MAX_VALUE; x++) {
      System.out.println(x);
    }
  }
}
Mr Jacques
+3  A: 

Another way to loop through every value using an int type.

public static void main(String[] args) {
    int i = Integer.MIN_VALUE;
    do {
        System.out.println(i);
    } while (i++ < Integer.MAX_VALUE);
}
Peter Lawrey
Cleverly done. +1
Michael Myers
+4  A: 

Ah, and here I had just started writing

System.out.println(-2147483648);
System.out.println(-2147483647);
System.out.println(-2147483646);

Okay, just give me a few weeks to finish typing this up ...

The instructions didn't say I have to use a loop, and at least this method doesn't have any overflow problems.

Jay
Write a program to write that program for you!
Michael Myers
Will result in ca 128GB of source code.
Totophil
@Totophil: But my company measure productivity by lines of code. By the time I get this program done, I'll be #1 in the department.
Jay
+2  A: 

Given the overview of the best answers, I realized that we're seriously lacking in the brute-force department. Jay's answer is nice, but it won't actually work. In the name of Science, I present - Bozo Range:

import java.util.Random;
import java.util.HashSet;

class Test {
    public static void main(String[] args) {
        Random rand = new Random();
        HashSet<Integer> found = new HashSet<Integer>();
        long range = Math.abs(Integer.MAX_VALUE - (long) Integer.MIN_VALUE);
        while (found.size() < range) {
            int n = rand.nextInt();
            if (!found.contains(n)) {
                found.add(n);
                System.out.println(n);
            }
        }
    }
}

Note that you'll need to set aside at least 4 GB of RAM in order to run this program. (Possibly 8 GB, if you're on a 64-bit machine, which you'll probably require to actually run this program...). This analysis doesn't count the bloat that the Integer class adds to any given int, either, nor the size of the HashSet itself.

Daniel Lew
Upvoted for the sheer fun on it. One of the key benefits I see behind this approach is the usage of standard collections library, meaning, for example, that you could easilly sort the numbers if you had to before outputting them...
Totophil
Am I missing something, or can't pagefiles be used to allow it to have less than 4GB of RAM?
Andrei Krotkov