This question exists because it has historical significance, but it is not considered a good, on-topic question for this site, so please do not use it as evidence that you can ask similar questions here. This question and its answers are frozen and cannot be changed. More info: help center.

137

The obvious answer is to use 500 calls to printf and print two numbers each time, no?
–
James McNellisDec 31 '10 at 6:59

The interview your chance to shine. Tell them "Without loops or conditionals? Child's play. I can do it without a computer!" Then pull out pen and notepad. They may give you a confused look, but just explain that if you can't count on built in language constructs, you really can't assume anything.
–
JohnFxDec 31 '10 at 18:40

@Zack: Let's get real, we're printing 1,000 lines from a program written to deliberately avoid loops. Performance is not an issue.
–
dreamlaxJan 3 '11 at 11:49

42

For those curious enough to compile this: in g++, set -ftemplate-depth-1000. The default template recursion maximum is 500.
–
TomJan 3 '11 at 18:47

10

@dreamlax: It's just one of those things I have learned from experience over the years: use '\n' unless you really want to flush, use ++i unless you actually need the former value of i, pass by const reference unless you have a good reason not to... When developers stop thinking about these (or never even start), they will, sooner or later, run into a problem where this matters, only they didn't even know there's spots where it might matter.
–
sbiJan 30 '11 at 23:43

Well, the code in this answer is obviously neither C nor C++, so this is fine only if we scrap the requirement. Then any answer may qualify because a hypothetical compiler might just produce the required program from any input.
–
eq-Jan 3 '11 at 19:34

16

I would really love an explanation of how and why this works, myself...
–
PP.Jan 4 '11 at 13:48

321

@PP, that's quite lengthy to explain, but basically, j is initially 1 because it's actually argc, which is 1 if the program is called without arguments. Then, j/1000 is 0 until j becomes 1000, after which it's 1. (exit - main) is, of course, the difference between the addresses of exit() and main(). That means (main + (exit - main)*(j/1000)) is main() until j becomes 1000, after which it becomes exit(). The end result is that main() is called when the program starts, then calls itself recursively 999 times while incrementing j, then calls exit(). Whew :)
–
Frédéric HamidiJan 4 '11 at 19:16

13

@Mark: this is non standard signature of main, you're disallowed to call main recursively, and the result of subtracting function pointers is undefined.
–
ybungalobillJan 17 '11 at 10:03

9

Yeah, yeah, it's not strictly legal C++ code for the reasons @ybungalobill gives, but I have to +1 for sheer insanity and the fact that it does compile and work on a few platforms. There are times when the correct response to "But it's not standard!" is "Who cares!" :)
–
j_random_hackerJan 26 '11 at 8:26

@Chris, they use the same logic expressed in macros or templates, blowing up the code size, right? You might as well generate the output string itself instead of a thousand printfs.
–
Darius BaconJan 3 '11 at 8:44

43

Well, nice effort, but rather odd that you didn't decompose 8 into 2*2*2 and thus use the unique prime factorisation
–
David HeffernanApr 11 '11 at 10:08

Also, I'd argue about a short-circuit not being a conditional... Not a statement, true, but a conditional expression, I'd say. Provided we define a conditional expression as "something which yields conditional jumps in assembler".
–
KosDec 31 '10 at 17:07

you should call fflush(stdout); after each printf()... When a program crashes it's not guaranteed that the output buffer will be printed on screen.
–
zakkJan 3 '11 at 1:47

10

@zakk: That's not strictly necessary - by default stdout is line buffered, so the \n will be enough to flush the output.
–
psmearsJan 4 '11 at 12:31

24

stdout is line buffered if it can be determined to be an interactive device , otherwise it's fully buffered. If the professor redirects stdout to a file for automated checking, you will fail :-)
–
paxdiabloJan 28 '11 at 3:50

3

+1 This is definitely one of my favorite answers. I love the intentional error but honestly, the interviewer deserved it.
–
quasiverseMar 27 '11 at 7:16

< is not a condition. It's a relational operator. if / else is a conditional statement. ?: is a conditional operator. < is just an operator that returns a boolean value. It's probably a single machine instruction with no jumps or anything.
–
Chris LutzDec 31 '10 at 9:38

@Jens Schauder: By taking advantage of lazy && evaluation in the first line of f().
–
Rafał DowgirdJan 3 '11 at 12:17

10

This isn't boring, it's simple. If you can do the same thing with a short function as you can with a huge mess of template magic, then you should do it with the function :)
–
amertuneJan 3 '11 at 17:27

21

The && is a conditional. A mathematical AND will evaluate both sides (like the Java & and the Ada "AND" does). && will evaluate the 2nd operator only if (here it is) the first is true. Or other example: In Ada it short-circuits operator is called "OR THEN" - using THEN to indicate the conditional aspect. Sorry, you could have just as well used the ? : operator.
–
MartinJan 3 '11 at 19:02

3

+1 Never thought of using boolean operators in this way.
–
quasiverseMar 27 '11 at 7:20

We can launch 1000 threads, each printing one of the numbers. Install OpenMPI, compile using mpicxx -o 1000 1000.cpp and run using mpirun -np 1000 ./1000. You will probably need to increase your descriptor limit using limit or ulimit. Note that this will be rather slow, unless you have loads of cores!

Of course, you can implement the same idea for other bases (2: print2 print4 print8 ...) but the number 1000 here suggested base 10. You can also reduce a little the number of lines adding intermediate functions: print2() print10() print20() print100() print200() print1000() and other equivalent alternatives.

I think std::copy treads a bit close to a loop.
–
Chris LutzDec 31 '10 at 9:51

3

@Chris Lutz: The implementation of copy is undefined. I may even use template code as above (you just don;t know). So you can't say it uses a loop because we don't know.
–
Loki AstariDec 31 '10 at 18:12

7

Actually, my nit pick wouldn't be the implicit loop in std::copy so much as the implicit conditional in the operator !=(). Regardless, it's a clever take on processing a range, and clever approaches is what I look for in response to questions like this.
–
Michael BurrDec 31 '10 at 23:05

This is for an 8MB stack. Each function invocation appears to take about 32 bytes (hence the 32 * 1000). But then when I ran it I only got to 804 (hence the 196 * 32; perhaps the C runtime has other parts in the stack that you have to deduct also).

Even in your comments you wrote "If yes then call recursive function to print". A conditional written in an unobvious way is still a conditional. The num default is also a conditional.
–
GerryAug 13 '11 at 18:54