322

Task: Print numbers from 1 to 1000 without using any loop or conditional statements. Don't just write the printf() or cout statement 1000 times.

How would you do that using C or C++?

WrightsCS
  • 50,551
  • 22
  • 134
  • 186
Saurabh Gokhale
  • 311
  • 3
  • 4
  • 5
  • So.... you question is *how do i do this*? – slugster Dec 31 '10 at 06:56
  • 137
    The obvious answer is to use 500 calls to `printf` and print two numbers each time, no? – James McNellis Dec 31 '10 at 06:59
  • 3
    I'm not a C or C++ guy but I'm assuming the answer is recursive. – jondavidjohn Dec 31 '10 at 07:00
  • 2
    Found a dupe : http://stackoverflow.com/questions/2044033/display-numbers-from-1-to-100-without-loops-or-conditions/ Tagged Java though. – Prasoon Saurav Dec 31 '10 at 07:03
  • 433
    printf("numbers from 1 to 1000"); – jondavidjohn Dec 31 '10 at 07:07
  • 7
    `:?` isn't a conditional _statement_ (it's an expression)... – Chris Lutz Dec 31 '10 at 09:48
  • 4
    Sounds like a CompSci homework question. :-) – RobertB Dec 31 '10 at 09:58
  • 6
    @Chris: `:?` is a "confused" face on some forum software. – BoltClock Dec 31 '10 at 11:59
  • 6
    Who votes it to be EXACT duplicate? The other question is about java, and it has different answers! The two languages are different! – Yakov Galka Dec 31 '10 at 12:48
  • I could understand no loops but why on earth no conditionals!? Theres no true way to do this without conditionals (unless its 1 to infinity) but i know it can be done without loops -edit- maybe templates as its compile time. Also i dont consider function calls as a loop (even if its recursion. Its just a jump/functional call). –  Dec 31 '10 at 14:59
  • 3
    lol this is not an exact duplicate of that java question. reopening... – Johannes Schaub - litb Dec 31 '10 at 15:22
  • Note that this is answered in the duplicate question for C++ here: http://stackoverflow.com/questions/2044033/display-numbers-from-1-to-100-without-loops-or-conditions/2046685#2046685 – Yishai Dec 31 '10 at 16:44
  • @Yishai: that someone answered a wrong question there doesn't make this question a duplicate. – Yakov Galka Dec 31 '10 at 16:50
  • 4
    I'd relish the opportunity to question the interviewer about what real insights into my skills and ability he/she was getting out of asking this question, especially since I'd already know that I wouldn't want to work there. – arcain Dec 31 '10 at 18:26
  • 127
    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. – JohnFx Dec 31 '10 at 18:40
  • 1
    -1 Because its duplicated and nonsense. Also kind of offtopic I think it fits better in programmers.stackchange or as an example to Code Golf and Programming Puzzles beta – Miguel López Dec 31 '10 at 19:25
  • 5
    If instead of C/C++ you were asked to do this in assembly language, with equivalent constraints, it would be impossible. So why are you not allowed to do things that your compiler will make your code do anyways? – Dan Burton Dec 31 '10 at 20:50
  • From my point of view *"Solve this puzzle with one more constraint than the last time it was posted"* question are unwanted, because they admit *"Solve the same puzzle with still another constraint"* and so on *ad nauseum*. To be sure the constructor solution is neat and understanding it means you know something about OO languages, but pone question on the matter is enough. – dmckee --- ex-moderator kitten Dec 31 '10 at 20:58
  • 4
    @dmckee: "Print 1 to 1000 without doing so." – BoltClock Dec 31 '10 at 21:27
  • 8
    Personally, I think there were several answers that had clever, interesting solutions. I also think that while this could easily be an awful interview question, there could be good value in it, as long as the interviewer is really looking not so much for a completely well-formed solution as looking for whether the interviewee considered approaches that indicate a knowledge of TMP or using constructs in unusual ways. I think it would be bad if this were used this as a pure 'got-it-right/wrong' question, but if it were used as the starting point of a discussion, I could see a lot of value. – Michael Burr Dec 31 '10 at 23:17
  • `printf("42");` or `"00101010"` or `"0x2A"` or `"6*9"` or `"54"`. – Mateen Ulhaq Jan 01 '11 at 03:03
  • 2
    Why are you people determined to close this one? – Prasoon Saurav Jan 02 '11 at 03:40
  • 7
    As someone who has interviewed many times and considered the "add a constraint" questions, there is definitely value to these questions. (a) You want to see how the interviewee deals with changes to the spec (b) see how the interviewee tries to find different approaches (c) weed out people who don't have any clue at all. Basically, the point in these questions is not the final answer, but the thought process. Another advantage of such simple questions is that they can weed out people who knew the question and said they'd never heard it before. I don't like to hire people who lie to me. – Nathan Fellman Jan 02 '11 at 19:04
  • 2
    Continuing my previous comment, I've hired many people who didn't solve the problems, and rejected many who did. A single question is never the basis for such a decision. – Nathan Fellman Jan 02 '11 at 19:05
  • 2
    @James Or you could just call printf 999 times, and use one of them to print two numbers. – Joel Jan 03 '11 at 03:07
  • People still equate conditional expressions with conditional statements. How nice. – Michael Foukarakis Jan 03 '11 at 10:28
  • 4
    Discussion on [proggit](http://www.reddit.com/r/programming/comments/ev2fc/printing_1_to_1000_without_loop_or_conditionals/). – moinudin Jan 03 '11 at 11:45
  • If they want developers who program like that, their codebase is going to be a bear to maintain. – Bruce Alderman Jan 03 '11 at 16:42
  • I'm just curious why this post got *91* +1's (and counting)? It's interesting, but is it really *that* interesting?! – user541686 Jan 04 '11 at 22:29
  • Most programmers do count from zero. – Martijn Courteaux Jan 19 '11 at 19:24
  • 3
    The question is lame, but the answers are awesome. – metamatt Jan 29 '11 at 01:36
  • Don't understand, people could grant bounty in a community wiki? – Hoàng Long Jan 29 '11 at 03:29
  • I think that the main goal of an interview question like this is to see if someone is capable of solving not just a complex problem, but also that they'll solve problems even if they're not that interesting. I wouldn't want to hire someone who wouldn't work on a project they weren't interested in. On the other hand, the problem with a question like this is that it could attract people who would rather spend their time solving puzzles instead of just getting the job done. – jamesmortensen Jan 30 '11 at 02:57
  • 2
    Beware, digits 0, 4, 6, 8 and 9 somewhat loop *per se*. – Benoit Feb 02 '11 at 08:27
  • 1
    @Benoit I would add that 1 is a loop beheld from a side. Maybe other digits are just some twisted loops looked from some funny angle =:P –  Feb 03 '11 at 09:34

106 Answers106

1194

This one actually compiles to assembly that doesn't have any conditionals:

#include <stdio.h>
#include <stdlib.h>

void main(int j) {
  printf("%d\n", j);
  (&main + (&exit - &main)*(j/1000))(j+1);
}


Edit: Added '&' so it will consider the address hence evading the pointer errors.

This version of the above in standard C, since it doesn't rely on arithmetic on function pointers:

#include <stdio.h>
#include <stdlib.h>

void f(int j)
{
    static void (*const ft[2])(int) = { f, exit };

    printf("%d\n", j);
    ft[j/1000](j + 1);
}

int main(int argc, char *argv[])
{
    f(1);
}
Alexei Sholik
  • 7,287
  • 2
  • 31
  • 41
Bill
  • 286
  • 1
  • 3
  • 10
  • 1
    Great solution. If it exited with status code 0 it would be perfect. I still upvoted it though... IDEA: replace (++j) with (++j * (1 - (j / 1001)) and it will exit with status code 0 :D – Johnco Jan 03 '11 at 16:27
  • 1
    Yep, I originally implemented it that way. But the brevity of this solution was too irresistible. – Bill Jan 03 '11 at 18:20
  • 17
    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 03 '11 at 19:34
  • 1
    Marvelous! I think it needs a little tweak: the order of evaluation of the j and the ++j in the last line is undefined (right?). I'd suggest: printf("%d\n", j++); (main + (exit - main)*(j/1001))(j); – Darius Bacon Jan 03 '11 at 21:06
  • 1
    On second thought, just change ++j to j+1. – Darius Bacon Jan 04 '11 at 00:07
  • 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 Hamidi Jan 04 '11 at 19:16
  • 7
    This is one of the most amazing abuses of C I have ever seen. But will it work on all platforms? – Qwertie Jan 04 '11 at 22:06
  • 4
    @Qwertie: You should read the international obfuscated C entries! Anyhow, some compilers might get pedantic about the prototype for main. – Bill Jan 04 '11 at 22:37
  • @eq - What am I missing? This compiles and runs just fine. – Em McDonald Jan 15 '11 at 18:46
  • 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. – Yakov Galka Jan 17 '11 at 10:03
  • I've [tried](http://stackoverflow.com/questions/4568645/printing-1-to-1000-without-loop-or-conditionals/4765553#4765553) to adapt this routine to make it more universal and standard. Surprisingly, it just works. – Martin Babacaev Jan 22 '11 at 02:31
  • @martin: nice, but the double ampersand operator is a GCC specific thing I think (not that my solution was fully portable) – Bill Jan 22 '11 at 18:00
  • 1
    @Bill Yes, you're right, it's not so "standard". Meanwhile I have updated my [answer](http://stackoverflow.com/questions/4568645/printing-1-to-1000-without-loop-or-conditionals/4765553#4765553) with another example :) – Martin Babacaev Jan 22 '11 at 18:53
  • @martin: oddly enough, typeof is a GNU extension too, I think. Nice solution though. – Bill Jan 22 '11 at 20:25
  • 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_hacker Jan 26 '11 at 08:26
  • Very clever! By the way, it IS possible that argc is 0 on some platforms when no commandline arguments are passed. I've never seen this in real life though, so bleh. –  Jan 28 '11 at 07:03
  • 1
    I'm with @ybungalobill here that you are not allowed to do this, but had to upvote nevertheless for its sheer madness. `:)` – sbi Jan 30 '11 at 22:27
  • Is actually wrong in C++ (maybe in C too, not sure). Stndard does allow only int main (int, char**) and int main() as valid entry points. – Valentin H Mar 07 '11 at 16:50
  • @ybungalobill : I don't see any reason not to subtract function pointers, any hint ? – Ben Mar 14 '11 at 18:52
  • @Ben: because the standard doesn't define what it means. I'm not sure if it allows it at all. – Yakov Galka Mar 15 '11 at 16:37
  • 1
    @ybungalobill: You're right, it doesn't allow it - the operands to the subtraction operator are either both arithmetic types; both pointers to compatible object types; or the left is an pointer to an object type and right is an integer type. Pointers to functions are not pointers to object types (and neither are pointers to `void`). – caf Mar 18 '11 at 05:59
  • 2
    @Sriram: Adding the `&` makes no difference to the legality of the code. – caf Mar 18 '11 at 06:02
  • @caf: Moreover, the result is defined only if both pointers point to the same array (I don't remember the exact formulation). – Yakov Galka Mar 18 '11 at 07:32
  • 2
    @caf the '&' actually makes no difference to the semantics but hopefully evades some pointer errors. At least in my case, I was using tcc for trying out the code and adding the '&' made it run. – Sriram Mar 20 '11 at 08:13
784

Compile time recursion! :P

#include <iostream>
template<int N>
struct NumberGeneration{
  static void out(std::ostream& os)
  {
    NumberGeneration<N-1>::out(os);
    os << N << std::endl;
  }
};
template<>
struct NumberGeneration<1>{
  static void out(std::ostream& os)
  {
    os << 1 << std::endl;
  }
};
int main(){
   NumberGeneration<1000>::out(std::cout);
}
Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
  • 1
    You know, that would make sense. But it's a weird question to ask if what they want to know is if the guy knows that templates are Turing complete. – Etienne de Martel Dec 31 '10 at 07:03
  • You can make it shorter with function templates. Also I know two more solutions to this question, unfortunately the question is closed now :( – Yakov Galka Dec 31 '10 at 07:16
  • @ybungalobill : But people are voting to reopen. [I dont like function templates :(] – Prasoon Saurav Dec 31 '10 at 07:18
  • 1
    Right you are, I missed the fact that the recursion comes before printing, more elegant than mine. – Motti Dec 31 '10 at 07:26
  • 1
    @Prasoon : Is that guaranteed to work? I think, no. I mean, what if instantiation depth exceeds at some point? – Nawaz Jan 02 '11 at 17:57
  • 1
    @Nawaz it will (does) produce a compile time error unless you modify the instantiation depth via command line arguments – Motti Jan 02 '11 at 21:09
  • 8
    Can somebody explain to me how this works? pretty impressive. – gath Jan 03 '11 at 05:18
  • 3
    You should use `<< '\n'` rather than `<< std::endl` to avoid unnecessary buffer flushes. (Yes, this works correctly on systems that use DOS newlines.) – zwol Jan 03 '11 at 05:43
  • 28
    @Zack: Let's get real, we're printing 1,000 lines from a program written to deliberately avoid loops. Performance is not an issue. – dreamlax Jan 03 '11 at 11:49
  • 5
    Neat. And the best thing of all is that it will be obvious he got help with his homework. :-) – Johan Levin Jan 03 '11 at 12:24
  • 42
    For those curious enough to compile this: in g++, set -ftemplate-depth-1000. The default template recursion maximum is 500. – Tom Jan 03 '11 at 18:47
  • 6
    This still uses conditionals: pattern matching is a glorified if. – David K. Jan 04 '11 at 06:33
  • 2
    @davidk01: The normal definitions of "loop" and "conditional" refer to operations that take place at runtime, not compile time, and this code is free of those. The code produced by the compiler will be 100% free of `CMP` and conditional jump instructions. – j_random_hacker Jan 26 '11 at 08:21
  • 1
    @Tom: it could also be modified to insrement by two every time and output two numbers, then, for a default template recursion depth of 500, you won't need any special compiler flags. :) –  Jan 28 '11 at 06:56
  • 4
    @dreamlax: This is one of those cases where I wish we could down-vote comments. This is a template-meta program, it will be executed by the compiler, at compile-time. The run-time program resulting from that does nothing but print 1000 numbers, so the __performance of the output is actually all that matters__, simply because after compilation there's nothing left but output. – sbi Jan 30 '11 at 22:16
  • @davidk01: Of course it does. Unless you write 1000 individual output statements you can't avoid using some kind of loop construct. – sbi Jan 30 '11 at 22:17
  • 2
    @sbi: The restrictions imposed were that it need only print the numbers 1 to 1,000 without loops or conditionals, it did not mention anything about the speed at which the program does it or how many stream flushes it is allowed. Using `'\n'` instead of `std::endl` isn't really all that useful. – dreamlax Jan 30 '11 at 22:37
  • 2
    @gath: It's a template-meta program with a mixed-in function call. The important thing is the recursive template instantiation. Note that each `NumberGeneration` will instantiate `NumberGeneration` (& calls its output function). This would be done until the compiler explodes, except the specialization `NumberGeneration<1>` doesn't instantiate any further template and so stops the recursion. Basically, template specialization is used for a compile-time `if`. [This famous article](http://erdani.com/publications/traits.html) by Alexandrescu explains the basics of this technique in detail. – sbi Jan 30 '11 at 23:23
  • 2
    @dreamlax: Of course the question didn't say anything about speed requirements. But _if_ we're talking about speed, the output is all that matters, because, at run-time, this program won't do anything but output. I agree with @Zack, Prasoon should have used `'\n'`, for the reason given by Zack. Thoughtlessly using `std::endl` is a common habit I see very often. I once had a coworker who spent days trying to find why a program's output speed was bad, until I pointed at the many `std::endl` calls. Replacing them sped up the app by a factor of ~6-8. I have paid close attention to them since. – sbi Jan 30 '11 at 23:29
  • 1
    @sbi: You're caring far too much about performance for such a useless application (not to mention risking premature optimisation). In fact, I even bothered to benchmark both and there was absolutely no measurable difference in execution time (both averaged roughly 20ms after about 40 runs each). – dreamlax Jan 30 '11 at 23:34
  • 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. – sbi Jan 30 '11 at 23:43
  • @sonicoder : Furthermore SO is a place for interesting things. For example read this : http://blog.stackoverflow.com/2011/03/a-new-name-for-stack-overflow-with-surprise-ending/ – Prasoon Saurav Mar 09 '11 at 14:35
  • 1
    @Beh Tou Cheh : I knew you were fishy. Your account got suspended, why? – Prasoon Saurav Mar 20 '11 at 13:20
  • @sbi I know on Linux systems that it will flush on '\n' anyway, so there's really no functional difference between std::endl and '\n'. std::endl is just guaranteed to flush, and it's operating system dependent if '\n' flushes. A majority of the time, there is no difference. – Jonathan Sternberg Mar 29 '11 at 06:46
  • @Jonathan: I'd be surprised if that's indeed the case, but I wouldn't rule it out. Even if it is true, though, the question didn't ask for a specific platform, so a good solution would be as good as possible on any platform. – sbi Mar 29 '11 at 09:23
  • 1
    @sbi I think I read it in another thread, but apparently '\n' will flush the buffer if the output is to something interactive. So '\n' will always flush for stdout (if stdout goes to a terminal), but it won't always flush if sent to a file. So they're the same if you output to a terminal, but different if it's a file. – Jonathan Sternberg Mar 29 '11 at 18:51
  • 2
    @Jonathan: I think what you're referring to is the _tying_ of streams. `std::cout` is _tied_ to `std::cin` so that, before `std::cin` awaits user input `std::cout` will be flushed. I haven't looked closely into any implementations of that, but I think it's just that: any _input_ operation will trigger the flushing of the output. – sbi Mar 29 '11 at 20:06
  • 1
    @Jonathan: bit pedantic, but `'\n'` vs `endl` is about the C++ library flushing it's buffers, so you're presumably describing GCC behaviour rather than Linux's. FWIW, my expectations (as a predominantly GCC/Linux developer) are that '\n' triggers flushing for `std::cerr` but not `std::cout`. I agree with others who've said Prasoon's code should use `'\n'`... it's just sloppy and misleading as is, uselessly begging the question "why's it flushing - is there something else going on here?". – Tony Delroy Jun 28 '11 at 05:24
  • Surely the template specialisations are conditionals :) – user2023370 Jan 06 '12 at 23:17
  • I don't understand the first `NumberGeneration::out(os);` call above the `os << N..` call. Won't that make infinite recursion until N is 1. But how can it print if it's being called *above* the `os << N..` line?? – David G Nov 27 '12 at 19:36
  • @0x499602D2 Read up on recursion. It's not an *infinite* recursion since it stops at 1. And then it prints out 1. Then the one that called 1 prints two... then the one that called that prints 3... until we get back to the original (1000, in this case) and it prints 1000. – Kitsune May 15 '13 at 18:09
  • Just write a function *int print(int n)* which prints the number and then returns *n>0 && print(n-1)*. – Ramy Al Zuhouri Jun 25 '13 at 22:12
544
#include <stdio.h>
int i = 0;
p()    { printf("%d\n", ++i); }
a()    { p();p();p();p();p(); }
b()    { a();a();a();a();a(); }
c()    { b();b();b();b();b(); }
main() { c();c();c();c();c();c();c();c(); return 0; }

I'm surprised nobody seems to have posted this -- I thought it was the most obvious way. 1000 = 5*5*5*8.

Darius Bacon
  • 14,921
  • 5
  • 53
  • 53
  • People have posted this. The other versions pass the number to print instead of using a global, but it's essentially the same solution. – Chris Lutz Jan 03 '11 at 06:23
  • 1
    @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 Bacon Jan 03 '11 at 08:44
  • Oh yeah, I see Keith's answer does generate the whole string, cool. :) I missed that. – Darius Bacon Jan 03 '11 at 08:47
  • 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 Heffernan Apr 11 '11 at 10:08
298

Looks like it doesn't need to use loops

printf("1 10 11 100 101 110 111 1000\n");
Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
270

Here are three solutions that I know. The second might be argued though.

// compile time recursion
template<int N> void f1()
{ 
    f1<N-1>(); 
    cout << N << '\n'; 
}

template<> void f1<1>() 
{ 
    cout << 1 << '\n'; 
}

// short circuiting (not a conditional statement)
void f2(int N)
{ 
    N && (f2(N-1), cout << N << '\n');
}

// constructors!
struct A {
    A() {
        static int N = 1;
        cout << N++ << '\n';
    }
};

int main()
{
    f1<1000>();
    f2(1000);
    delete[] new A[1000]; // (3)
    A data[1000]; // (4) added by Martin York
}

[ Edit: (1) and (4) can be used for compile time constants only, (2) and (3) can be used for runtime expressions too — end edit. ]

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
  • 1
    constructor one is cool. I'll mention i seen a java question where they have an array of 1000 and do arr[param] = val which will throw when it gets to 1000 and is caught at the end of main(). –  Dec 31 '10 at 14:55
  • (4) can be used for runtime values too under modern compilers which support C99 extensions in C++ mode. Come on, it's 2010, let's not be afraid of VLAs :) – Kos Dec 31 '10 at 17:06
  • 5
    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". – Kos Dec 31 '10 at 17:07
  • 5
    Question that hit me when reading the constructor one: Does the standard mandate that each item in the array be constructed in sequence? It would matter if the constructor had side effects. I'm sure every sane compiler implements it as a 0->1000 loop but I wonder if you could still be compliant and loop backwards... – Joseph Garvin Jan 02 '11 at 23:42
  • 6
    @Joseph - The constructor one shouldn't be affected by what order the individual objects are initiated, but it is a good question. – Chris Lutz Jan 03 '11 at 02:40
  • 12
    @Joseph this is defined by 12.6/3 (C++03). Initialization is done in subscription order. – Johannes Schaub - litb Jan 03 '11 at 09:56
  • 2
    @Joseph: And they're destructed in reverse order too, so you could use a destructor just as easily :) – j_random_hacker Jan 03 '11 at 10:00
  • 1
    But the && is essential a conditional: a short form of x ? y : false. A true AND will evaluate both sides. – Martin Jan 03 '11 at 19:10
263

I'm not writing the printf statement 1000 times!

printf("1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n40\n41\n42\n43\n44\n45\n46\n47\n48\n49\n50\n51\n52\n53\n54\n55\n56\n57\n58\n59\n60\n61\n62\n63\n64\n65\n66\n67\n68\n69\n70\n71\n72\n73\n74\n75\n76\n77\n78\n79\n80\n81\n82\n83\n84\n85\n86\n87\n88\n89\n90\n91\n92\n93\n94\n95\n96\n97\n98\n99\n100\n101\n102\n103\n104\n105\n106\n107\n108\n109\n110\n111\n112\n113\n114\n115\n116\n117\n118\n119\n120\n121\n122\n123\n124\n125\n126\n127\n128\n129\n130\n131\n132\n133\n134\n135\n136\n137\n138\n139\n140\n141\n142\n143\n144\n145\n146\n147\n148\n149\n150\n151\n152\n153\n154\n155\n156\n157\n158\n159\n160\n161\n162\n163\n164\n165\n166\n167\n168\n169\n170\n171\n172\n173\n174\n175\n176\n177\n178\n179\n180\n181\n182\n183\n184\n185\n186\n187\n188\n189\n190\n191\n192\n193\n194\n195\n196\n197\n198\n199\n200\n201\n202\n203\n204\n205\n206\n207\n208\n209\n210\n211\n212\n213\n214\n215\n216\n217\n218\n219\n220\n221\n222\n223\n224\n225\n226\n227\n228\n229\n230\n231\n232\n233\n234\n235\n236\n237\n238\n239\n240\n241\n242\n243\n244\n245\n246\n247\n248\n249\n250\n251\n252\n253\n254\n255\n256\n257\n258\n259\n260\n261\n262\n263\n264\n265\n266\n267\n268\n269\n270\n271\n272\n273\n274\n275\n276\n277\n278\n279\n280\n281\n282\n283\n284\n285\n286\n287\n288\n289\n290\n291\n292\n293\n294\n295\n296\n297\n298\n299\n300\n301\n302\n303\n304\n305\n306\n307\n308\n309\n310\n311\n312\n313\n314\n315\n316\n317\n318\n319\n320\n321\n322\n323\n324\n325\n326\n327\n328\n329\n330\n331\n332\n333\n334\n335\n336\n337\n338\n339\n340\n341\n342\n343\n344\n345\n346\n347\n348\n349\n350\n351\n352\n353\n354\n355\n356\n357\n358\n359\n360\n361\n362\n363\n364\n365\n366\n367\n368\n369\n370\n371\n372\n373\n374\n375\n376\n377\n378\n379\n380\n381\n382\n383\n384\n385\n386\n387\n388\n389\n390\n391\n392\n393\n394\n395\n396\n397\n398\n399\n400\n401\n402\n403\n404\n405\n406\n407\n408\n409\n410\n411\n412\n413\n414\n415\n416\n417\n418\n419\n420\n421\n422\n423\n424\n425\n426\n427\n428\n429\n430\n431\n432\n433\n434\n435\n436\n437\n438\n439\n440\n441\n442\n443\n444\n445\n446\n447\n448\n449\n450\n451\n452\n453\n454\n455\n456\n457\n458\n459\n460\n461\n462\n463\n464\n465\n466\n467\n468\n469\n470\n471\n472\n473\n474\n475\n476\n477\n478\n479\n480\n481\n482\n483\n484\n485\n486\n487\n488\n489\n490\n491\n492\n493\n494\n495\n496\n497\n498\n499\n500\n501\n502\n503\n504\n505\n506\n507\n508\n509\n510\n511\n512\n513\n514\n515\n516\n517\n518\n519\n520\n521\n522\n523\n524\n525\n526\n527\n528\n529\n530\n531\n532\n533\n534\n535\n536\n537\n538\n539\n540\n541\n542\n543\n544\n545\n546\n547\n548\n549\n550\n551\n552\n553\n554\n555\n556\n557\n558\n559\n560\n561\n562\n563\n564\n565\n566\n567\n568\n569\n570\n571\n572\n573\n574\n575\n576\n577\n578\n579\n580\n581\n582\n583\n584\n585\n586\n587\n588\n589\n590\n591\n592\n593\n594\n595\n596\n597\n598\n599\n600\n601\n602\n603\n604\n605\n606\n607\n608\n609\n610\n611\n612\n613\n614\n615\n616\n617\n618\n619\n620\n621\n622\n623\n624\n625\n626\n627\n628\n629\n630\n631\n632\n633\n634\n635\n636\n637\n638\n639\n640\n641\n642\n643\n644\n645\n646\n647\n648\n649\n650\n651\n652\n653\n654\n655\n656\n657\n658\n659\n660\n661\n662\n663\n664\n665\n666\n667\n668\n669\n670\n671\n672\n673\n674\n675\n676\n677\n678\n679\n680\n681\n682\n683\n684\n685\n686\n687\n688\n689\n690\n691\n692\n693\n694\n695\n696\n697\n698\n699\n700\n701\n702\n703\n704\n705\n706\n707\n708\n709\n710\n711\n712\n713\n714\n715\n716\n717\n718\n719\n720\n721\n722\n723\n724\n725\n726\n727\n728\n729\n730\n731\n732\n733\n734\n735\n736\n737\n738\n739\n740\n741\n742\n743\n744\n745\n746\n747\n748\n749\n750\n751\n752\n753\n754\n755\n756\n757\n758\n759\n760\n761\n762\n763\n764\n765\n766\n767\n768\n769\n770\n771\n772\n773\n774\n775\n776\n777\n778\n779\n780\n781\n782\n783\n784\n785\n786\n787\n788\n789\n790\n791\n792\n793\n794\n795\n796\n797\n798\n799\n800\n801\n802\n803\n804\n805\n806\n807\n808\n809\n810\n811\n812\n813\n814\n815\n816\n817\n818\n819\n820\n821\n822\n823\n824\n825\n826\n827\n828\n829\n830\n831\n832\n833\n834\n835\n836\n837\n838\n839\n840\n841\n842\n843\n844\n845\n846\n847\n848\n849\n850\n851\n852\n853\n854\n855\n856\n857\n858\n859\n860\n861\n862\n863\n864\n865\n866\n867\n868\n869\n870\n871\n872\n873\n874\n875\n876\n877\n878\n879\n880\n881\n882\n883\n884\n885\n886\n887\n888\n889\n890\n891\n892\n893\n894\n895\n896\n897\n898\n899\n900\n901\n902\n903\n904\n905\n906\n907\n908\n909\n910\n911\n912\n913\n914\n915\n916\n917\n918\n919\n920\n921\n922\n923\n924\n925\n926\n927\n928\n929\n930\n931\n932\n933\n934\n935\n936\n937\n938\n939\n940\n941\n942\n943\n944\n945\n946\n947\n948\n949\n950\n951\n952\n953\n954\n955\n956\n957\n958\n959\n960\n961\n962\n963\n964\n965\n966\n967\n968\n969\n970\n971\n972\n973\n974\n975\n976\n977\n978\n979\n980\n981\n982\n983\n984\n985\n986\n987\n988\n989\n990\n991\n992\n993\n994\n995\n996\n997\n998\n999\n1000\n");

You're welcome ;)

Philip Potter
  • 8,975
  • 2
  • 37
  • 47
Martin Thurau
  • 7,564
  • 7
  • 43
  • 80
212
printf("%d\n", 2);
printf("%d\n", 3);

It doesn't print all the numbers, but it does "Print numbers from 1 to 1000." Ambiguous question for the win! :)

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
  • 77
    my favorite after 'printf("numbers from 1 to 1000")' - silly questions require silly answers. – SEngstrom Jan 01 '11 at 06:57
  • this is awesome. +1 for taking advantage of the ambiguity in the question. haha – Nawaz Jan 02 '11 at 18:06
  • 2
    Edited; in no way, shape, or form did this code `print "Print numbers from 1 to 1000."` - ambiguous question for the win, inaccurate descriptions suck :) – sehe Oct 26 '11 at 00:38
  • Wow, there's been a bit of vandalism on this question's answers lately. Something tells me we should upgrade that lock to a historical lock. – BoltClock Nov 29 '12 at 04:16
172

Trigger a fatal error! Here's the file, countup.c:

#include <stdio.h>
#define MAX 1000
int boom;
int foo(n) {
    boom = 1 / (MAX-n+1);
    printf("%d\n", n);
    foo(n+1);
}
int main() {
    foo(1);
}

Compile, then execute on a shell prompt:

$ ./countup
1
2
3
...
996
997
998
999
1000
Floating point exception
$

This does indeed print the numbers from 1 to 1000, without any loops or conditionals!

Aaron Maxwell
  • 31
  • 1
  • 1
  • 2
  • 43
    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. – zakk Jan 03 '11 at 01:47
  • 10
    @zakk: That's not strictly necessary - by default stdout is line buffered, so the `\n` will be enough to flush the output. – psmears Jan 04 '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 :-) – paxdiablo Jan 28 '11 at 03:50
  • danger of stackoverflow (for example in an embedded enviroment) – Hernán Eche Feb 03 '11 at 18:31
166

Using system commands:

system("/usr/bin/seq 1000");
moinudin
  • 134,091
  • 45
  • 190
  • 216
  • 15
    High chance `/usr/bin/seq` uses a loop internally. :) –  Jun 06 '11 at 14:09
  • @jokester: you mean, because Solaris/BSD doesn't have a `seq` utility (in the default setup)? – sehe Oct 26 '11 at 00:40
  • I hate to say this (well, no I don't), but there's a bug in your solution. It doesn't print out the right set of numbers. :) Here's the fix: ``system("/bin/echo {1..1000}");`` If only you had written the unit test first... – Don Branson Nov 26 '12 at 14:34
  • 1
    Some bright dude decided to change my answer, so that's not my mistake. – moinudin Nov 26 '12 at 20:04
100

Untested, but should be vanilla standard C:

void yesprint(int i);
void noprint(int i);

typedef void(*fnPtr)(int);
fnPtr dispatch[] = { noprint, yesprint };

void yesprint(int i) {
    printf("%d\n", i);
    dispatch[i < 1000](i + 1);
}

void noprint(int i) { /* do nothing. */ }

int main() {
    yesprint(1);
}
munificent
  • 11,946
  • 2
  • 38
  • 55
  • 29
    @Prasoon: It's a relation. – Yakov Galka Dec 31 '10 at 08:03
  • 28
    requirement is "no conditionals" (if, switch, etc). not "no conditions" – jon_darkstar Dec 31 '10 at 08:45
  • 1
    Anyway, "i < 1000" is a condition, but I like this solution. – Huang F. Lei Dec 31 '10 at 09:31
  • 32
    `<` 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 Lutz Dec 31 '10 at 09:38
  • 1
    Just a comment - the array declaration should be `fnPtr dispatch[] = { noprint, yesprint };` since your `[i <= 1000]` would be `1` if true (and would call `noprint` in your existing code). Additionally, your expression only needs to be `[i < 1000]` since on `999`, it would call `yesprint` with `i+1 == 1000`. Other than that, +1 for your approach. – wkl Dec 31 '10 at 15:51
  • Nice, but recursive, which is the biggest drawback here. – Kos Dec 31 '10 at 17:10
  • 1
    Nice idea, but the way you wrote it won't compile nor work. Here is a corrected version : http://ideone.com/AeglZ – houbysoft Dec 31 '10 at 19:36
  • 1
    @Martin: The standard says that `true`, when converted to an integer, is `1`. So whatever system you've seen where it wasn't, wasn't C and wasn't C++. – Ben Voigt Jan 01 '11 at 01:39
  • @Ben Voigt: Darn showing my age (Updated since I last read the C standard). – Martin York Jan 01 '11 at 01:57
  • @Martin: Dude, even C89 says Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false. The result has type int. And `&&`, `||`, and `!` follow the same rule. It gets worse: the 1974 version did too: [The value of ``expression relation expression'' is 1 if the relation is true, and 0 if false](http://www.lysator.liu.se/c/bwk-tutor.html#relational). I suspect you're thinking of another language. – Ben Voigt Jan 01 '11 at 02:05
  • @Ben Voigt: I could be wrong. But I remember that the only guarantees we had were `#define FALSE 0` and `#define TRUE (!FALSE)`. Even back then we had to write portable code (shesh for the airforce) and these two systems actually had different truth values (System A 1: System B 255) (now it could have been one was non standard C (people were not as strict about it back then (but I am sure I looked it up (maybe I just messed up)). I suppose a tutorial from Bell is as close to the standard as we are getting from those days. – Martin York Jan 01 '11 at 19:01
  • 1
    @Martin: My copy of K&R (2nd Ed) says that relational operators return 0 or 1 by definition. You can rely on those int values. – munificent Jan 01 '11 at 23:15
  • 12
    @Chris Lutz: On x86, it's 3 instructions: `cmpl`, `setle`, and `movzbl`. x86-64 is that plus a `cltq`. PowerPC is 2 instructions: `cmpwi` and `crnot`. – Adam Rosenfield Jan 02 '11 at 20:53
  • @Adam - My bad. Still no jumps, unless I know far less about assembly than I thought I did. – Chris Lutz Jan 03 '11 at 00:34
  • @Chris Lutz: Correct, there are no jumps in those instruction sequences. It's still fast, even though it's 2-4 instructions, because there are no branch mispredictions. – Adam Rosenfield Jan 03 '11 at 01:50
  • Actually I lied, the PowerPC sequence is 4 instructions: `cmpwi`, `crnot`, `mfcr`, and `rlwinm`. – Adam Rosenfield Jan 03 '11 at 02:05
  • 2
    If using `i < 1000` is contentious, you can use another indirection. Add `static int jeez[1001]; jeez[1000] = 1;` and replace `i < 1000` with `1 - jeez[i]`. (Static arrays are initialised to zero.) – j_random_hacker Jan 03 '11 at 10:17
  • Pedants, the requirement is 'no conditional statements', not 'no conditional operators'. Also, assembly is not C nor C++, and vice versa. – Michael Foukarakis Jan 03 '11 at 14:17
  • 4
    `1 - i / 1000`. No comparisons! – Thai Jan 04 '11 at 16:28
  • 3
    There's nothing contentious about `i < 1000`. It's no more conditional than `-`: there's no flow control or short-circuiting involved. – munificent Jan 04 '11 at 16:32
96

A bit boring compared to others here, but probably what they're looking for.

#include <stdio.h>

int f(int val) {
    --val && f(val);
    return printf( "%d\n", val+1);
}

void main(void) {
    f(1000);
}
Aaron
  • 1
  • 1
  • 2
  • Made it shorter. set i=1 outside of main and then inside of main: printf("%d\n", 11 - i) && --i && main(i); – jftuga Jan 03 '11 at 11:43
  • 3
    @Jens Schauder: By taking advantage of lazy `&&` evaluation in the first line of `f()`. – Rafał Dowgird Jan 03 '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 :) – amertune Jan 03 '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. – Martin Jan 03 '11 at 19:02
  • No need to apologize. && is a comparison operator. The ternary operator is a conditional. – Aaron Jan 03 '11 at 23:37
71

The task never specified that the program must terminate after 1000.

void f(int n){
   printf("%d\n",n);
   f(n+1);
}

int main(){
   f(1);
}

(Can be shortened to this if you run ./a.out with no extra params)

void main(int n) {
   printf("%d\n", n);
   main(n+1);
}
Brian
  • 1,026
  • 11
  • 18
  • It does not stop at 1000, though. It just keeps going. – Remy Lebeau Jan 07 '11 at 08:34
  • Can be shortened only if you scrap the requirement of C or C++. Then any "program" will do, because a theoretical compiler could generate the program you want (from any input). – eq- Jan 12 '11 at 10:43
  • @eq Again, this compiles and runs just fine… – Em McDonald Jan 15 '11 at 18:49
  • That has to be my favorite (the short version). Simple and clear. – Sascha Feb 03 '11 at 08:58
  • 72
    As an afterthought: we can even evade _apparent_ math. If we employ `rand()`, we shall print all of them numbers from 1 to 1000. **Eventually** =:P –  Feb 03 '11 at 09:23
  • 5
    @pooh: Not necessarily, since rand() has a chance of repeating after certain sequence, and that sequence might be not fall in the solution set for this problem – dchhetri Jan 06 '12 at 05:36
71

Easy as pie! :P

#include <iostream>

static int current = 1;

struct print
{
    print() { std::cout << current++ << std::endl; }
};

int main()
{
    print numbers [1000];
}
Zelix
  • 1,914
  • 1
  • 14
  • 11
65
#include <stdio.h>
#define Out(i)       printf("%d\n", i++);
#define REP(N)       N N N N N N N N N N
#define Out1000(i)   REP(REP(REP(Out(i))));
void main()
{
 int i = 1;
 Out1000(i);
}
MangleSky
  • 1
  • 1
  • 2
42

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!

#include <cstdio>
#include <mpi.h>
using namespace std;

int main(int argc, char **argv) {
  MPI::Init(argc, argv);
  cout << MPI::COMM_WORLD.Get_rank() + 1 << endl;
  MPI::Finalize();
}

Of course, the numbers won't necessarily be printed in order, but the question doesn't require them to be ordered.

moinudin
  • 134,091
  • 45
  • 190
  • 216
  • 1
    Implicit loop in the library? But +1 anyway for a new approach. – Chris Lutz Jan 03 '11 at 06:18
  • 11
    @Chris Don't most solutions have a hidden loop somewhere? – moinudin Jan 03 '11 at 10:20
  • I suppose, if you take the "loops in the compiler" approach. Since (outside of a possible loop over the arguments in `MPI::Init()`) I can't imagine any loops in the actual binary of your 1000.cpp program, I gave you a +1, even though there are certainly loops running when you execute it. – Chris Lutz Jan 03 '11 at 10:30
40

With plain C:

#include<stdio.h>

/* prints number  i */ 
void print1(int i) {
    printf("%d\n",i);
}

/* prints 10 numbers starting from i */ 
void print10(int i) {
    print1(i);
    print1(i+1);
    print1(i+2);
    print1(i+3);
    print1(i+4);
    print1(i+5);
    print1(i+6);
    print1(i+7);
    print1(i+8);
    print1(i+9);
}

/* prints 100 numbers starting from i */ 
void print100(int i) {
    print10(i);
    print10(i+10);
    print10(i+20);
    print10(i+30);
    print10(i+40);
    print10(i+50);
    print10(i+60);
    print10(i+70);
    print10(i+80);
    print10(i+90);
}

/* prints 1000 numbers starting from i */ 
void print1000(int i) {
    print100(i);
    print100(i+100);
    print100(i+200);
    print100(i+300);
    print100(i+400);
    print100(i+500);
    print100(i+600);
    print100(i+700);
    print100(i+800);
    print100(i+900);
}


int main() {
        print1000(1);
        return 0;
}

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.

leonbloy
  • 73,180
  • 20
  • 142
  • 190
  • Why does the number 1000 suggest base 10? In any positional notation with base `B`, 1000 is a perfectly valid number and always equals `B^3`. – Philip Feb 03 '12 at 08:39
  • I just meant that, given how the number is represented in base 10, the factorization "10x10x10" suggested itself, but that other alternatives are possible. I guess I should have said "factorization" instead of "base" – leonbloy Mar 12 '13 at 20:38
34

Just use std::copy() with a special iterator.

#include <algorithm>
#include <iostream>
#include <iterator>

struct number_iterator
{
    typedef std::input_iterator_tag iterator_category;
    typedef int                     value_type;
    typedef std::size_t             difference_type;
    typedef int*                    pointer;
    typedef int&                    reference;

    number_iterator(int v): value(v)                {}
    bool operator != (number_iterator const& rhs)   { return value != rhs.value;}
    number_iterator operator++()                    { ++value; return *this;}
    int operator*()                                 { return value; }
    int value;
};



int main()
{
    std::copy(number_iterator(1), 
              number_iterator(1001), 
              std::ostream_iterator<int>(std::cout, " "));
}
Martin York
  • 257,169
  • 86
  • 333
  • 562
  • I think your code starts from 0. Also agree with Chris, the question as I saw it years ago was stated as "without any libraries except for IO". yet +1 :) – Yakov Galka Dec 31 '10 at 10:12
  • 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. – Martin York Dec 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 Burr Dec 31 '10 at 23:05
  • implementation specific is undefined – selvaiyyamperumal Dec 28 '11 at 07:55
  • @selvaiyyamperumal: Not sure exactly what you are talking about. But if you are talking about behavior then the standard disagrees with you. "Implementation Defined behavior" means it is well defined but must be explicitly documented by the implementation. "Undefined Behavior" means anything can happen. – Martin York Dec 28 '11 at 08:06
33

Function pointer (ab)use. No preprocessor magic to increase output. ANSI C.

#include <stdio.h>

int i=1;

void x10( void (*f)() ){
    f(); f(); f(); f(); f();
    f(); f(); f(); f(); f();
}

void I(){printf("%i ", i++);}
void D(){ x10( I ); }
void C(){ x10( D ); }
void M(){ x10( C ); }

int main(){
    M();
}
Filipe Z
  • 1
  • 1
  • 2
  • 3
    This is what I was thinking of. A previous person said that 5*5*5*8=1000. I thought that it was funny he was missing the obvious 10^3. Nice solution! – Evan Moran Mar 15 '11 at 01:02
32
#include <iostream>
#include <iterator>
using namespace std;

int num() { static int i = 1; return i++; }
int main() { generate_n(ostream_iterator<int>(cout, "\n"), 1000, num); }
Dustin
  • 1,030
  • 11
  • 15
30

Ugly C answer (unrolled for only one stack frame per power of 10):

#define f5(i) f(i);f(i+j);f(i+j*2);f(i+j*3);f(i+j*4)
void f10(void(*f)(int), int i, int j){f5(i);f5(i+j*5);}
void p1(int i){printf("%d,",i);}
#define px(x) void p##x##0(int i){f10(p##x, i, x);}
px(1); px(10); px(100);

void main()
{
  p1000(1);
}
Martin
  • 113
  • 1
  • 4
  • 3
    all things alright, but why "void main()"? bad habits seldom go? :P – Nawaz Jan 02 '11 at 18:20
  • 30
    @Nawaz: Because this is secretly a Windows GUI app, so it doesn't matter. I only called it "main" because I was thinking about lobsters and have terrible spelling. – Martin Jan 02 '11 at 22:56
29

Stack overflow:

#include <stdio.h>

static void print_line(int i)
{   
 printf("%d\n", i); 
 print_line(i+1);
}   

int main(int argc, char* argv[])
{   
 //get up near the stack limit
 char tmp[ 8388608 - 32 * 1000 - 196 * 32 ];
 print_line(1);
} 

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).

25

Fun with function pointers (none of that new-fangled TMP needed):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>


#define MSB(typ) ((sizeof(typ) * CHAR_BIT) - 1)

void done(int x, int y);
void display(int x, int y);

void (*funcs[])(int,int)  = {
    done,
    display
};

void done(int x, int y)
{
    exit(0);
}

void display(int x, int limit)
{
    printf( "%d\n", x);
    funcs[(((unsigned int)(x-limit)) >> MSB(int)) & 1](x+1, limit);
}


int main()
{
    display(1, 1000);
    return 0;
}

As a side note: I took the prohibition against conditionals to extend to logical and relational operators as well. If you allow logical negation, the recursive call can be simplified to:

funcs[!!(limit-1)](x+1, limit-1);
Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • i like the way you've got it with the bit shift. but with your simplification afterthought, what does the double bang do? its bitwise or logical? im lost and google got me going around in circles `funcs[!!(limit-1)](x+1, limit-1); ` – jon_darkstar Dec 31 '10 at 08:52
  • I'd rather have a single `!` and switch the function pointer array elements, but I don't know if that will play well with your other craziness. – Chris Lutz Dec 31 '10 at 09:42
  • @Chris: I agree completely - but I didn't consider using logical/relation operators until after posting, and I figured a single-line patch would be more appropriate. Besides, it fits in a little better with the whole obfuscated feel of the problem. – Michael Burr Dec 31 '10 at 18:39
24

I feel this answer will be very simple and easy to understand.

int print1000(int num=1)
{
    printf("%d\n", num);

    // it will check first the num is less than 1000. 
    // If yes then call recursive function to print
    return num<1000 && print1000(++num); 
}

int main()
{
    print1000();
    return 0;        
}
Rajeev
  • 1,196
  • 3
  • 14
  • 21
  • 3
    Your answer uses conditional statements, which are forbidden according to the question. – stevelove Jan 08 '11 at 05:36
  • 4
    conditional statements are if else etc. I just used a logical operation!! Hpe it is clear! – Rajeev Jan 08 '11 at 06:45
  • 2
    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. – Gerry Aug 13 '11 at 18:54
23

I missed all the fun, all the good C++ answers have already been posted !

This is the weirdest thing I could come up with, I wouldn't bet it's legal C99 though :p

#include <stdio.h>

int i = 1;
int main(int argc, char *argv[printf("%d\n", i++)])
{
  return (i <= 1000) && main(argc, argv);
}

Another one, with a little cheating :

#include <stdio.h>
#include <boost/preprocessor.hpp>

#define ECHO_COUNT(z, n, unused) n+1
#define FORMAT_STRING(z, n, unused) "%d\n"

int main()
{
    printf(BOOST_PP_REPEAT(1000, FORMAT_STRING, ~), BOOST_PP_ENUM(LOOP_CNT, ECHO_COUNT, ~));
}

Last idea, same cheat :

#include <boost/preprocessor.hpp>
#include <iostream>

int main()
{
#define ECHO_COUNT(z, n, unused) BOOST_PP_STRINGIZE(BOOST_PP_INC(n))"\n"
    std::cout << BOOST_PP_REPEAT(1000, ECHO_COUNT, ~) << std::endl;
}
icecrime
  • 74,451
  • 13
  • 99
  • 111
22

Easy as pie:

int main(int argc, char* argv[])
{
    printf(argv[0]);
}

method of execution:

printer.exe "1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;30;31;32;33;34;35;36;37;38;39;40;41;42;43;44;45;46;47;48;49;50;51;52;53;54;55;56;57;58;59;60;61;62;63;64;65;66;67;68;69;70;71;72;73;74;75;76;77;78;79;80;81;82;83;84;85;86;87;88;89;90;91;92;93;94;95;96;97;98;99;100;101;102;103;104;105;106;107;108;109;110;111;112;113;114;115;116;117;118;119;120;121;122;123;124;125;126;127;128;129;130;131;132;133;134;135;136;137;138;139;140;141;142;143;144;145;146;147;148;149;150;151;152;153;154;155;156;157;158;159;160;161;162;163;164;165;166;167;168;169;170;171;172;173;174;175;176;177;178;179;180;181;182;183;184;185;186;187;188;189;190;191;192;193;194;195;196;197;198;199;200;201;202;203;204;205;206;207;208;209;210;211;212;213;214;215;216;217;218;219;220;221;222;223;224;225;226;227;228;229;230;231;232;233;234;235;236;237;238;239;240;241;242;243;244;245;246;247;248;249;250;251;252;253;254;255;256;257;258;259;260;261;262;263;264;265;266;267;268;269;270;271;272;273;274;275;276;277;278;279;280;281;282;283;284;285;286;287;288;289;290;291;292;293;294;295;296;297;298;299;300;301;302;303;304;305;306;307;308;309;310;311;312;313;314;315;316;317;318;319;320;321;322;323;324;325;326;327;328;329;330;331;332;333;334;335;336;337;338;339;340;341;342;343;344;345;346;347;348;349;350;351;352;353;354;355;356;357;358;359;360;361;362;363;364;365;366;367;368;369;370;371;372;373;374;375;376;377;378;379;380;381;382;383;384;385;386;387;388;389;390;391;392;393;394;395;396;397;398;399;400;401;402;403;404;405;406;407;408;409;410;411;412;413;414;415;416;417;418;419;420;421;422;423;424;425;426;427;428;429;430;431;432;433;434;435;436;437;438;439;440;441;442;443;444;445;446;447;448;449;450;451;452;453;454;455;456;457;458;459;460;461;462;463;464;465;466;467;468;469;470;471;472;473;474;475;476;477;478;479;480;481;482;483;484;485;486;487;488;489;490;491;492;493;494;495;496;497;498;499;500;501;502;503;504;505;506;507;508;509;510;511;512;513;514;515;516;517;518;519;520;521;522;523;524;525;526;527;528;529;530;531;532;533;534;535;536;537;538;539;540;541;542;543;544;545;546;547;548;549;550;551;552;553;554;555;556;557;558;559;560;561;562;563;564;565;566;567;568;569;570;571;572;573;574;575;576;577;578;579;580;581;582;583;584;585;586;587;588;589;590;591;592;593;594;595;596;597;598;599;600;601;602;603;604;605;606;607;608;609;610;611;612;613;614;615;616;617;618;619;620;621;622;623;624;625;626;627;628;629;630;631;632;633;634;635;636;637;638;639;640;641;642;643;644;645;646;647;648;649;650;651;652;653;654;655;656;657;658;659;660;661;662;663;664;665;666;667;668;669;670;671;672;673;674;675;676;677;678;679;680;681;682;683;684;685;686;687;688;689;690;691;692;693;694;695;696;697;698;699;700;701;702;703;704;705;706;707;708;709;710;711;712;713;714;715;716;717;718;719;720;721;722;723;724;725;726;727;728;729;730;731;732;733;734;735;736;737;738;739;740;741;742;743;744;745;746;747;748;749;750;751;752;753;754;755;756;757;758;759;760;761;762;763;764;765;766;767;768;769;770;771;772;773;774;775;776;777;778;779;780;781;782;783;784;785;786;787;788;789;790;791;792;793;794;795;796;797;798;799;800;801;802;803;804;805;806;807;808;809;810;811;812;813;814;815;816;817;818;819;820;821;822;823;824;825;826;827;828;829;830;831;832;833;834;835;836;837;838;839;840;841;842;843;844;845;846;847;848;849;850;851;852;853;854;855;856;857;858;859;860;861;862;863;864;865;866;867;868;869;870;871;872;873;874;875;876;877;878;879;880;881;882;883;884;885;886;887;888;889;890;891;892;893;894;895;896;897;898;899;900;901;902;903;904;905;906;907;908;909;910;911;912;913;914;915;916;917;918;919;920;921;922;923;924;925;926;927;928;929;930;931;932;933;934;935;936;937;938;939;940;941;942;943;944;945;946;947;948;949;950;951;952;953;954;955;956;957;958;959;960;961;962;963;964;965;966;967;968;969;970;971;972;973;974;975;976;977;978;979;980;981;982;983;984;985;986;987;988;989;990;991;992;993;994;995;996;997;998;999;1000"

The specification does not say that the sequence must be generated inside the code :)

Rodrigo
  • 4,365
  • 3
  • 31
  • 49
18
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;

class Printer
{
public:
 Printer() { cout << ++i_ << "\n"; }
private:
 static unsigned i_;
};

unsigned Printer::i_ = 0;

int main()
{
 Printer p[1000];
}
John Dibling
  • 99,718
  • 31
  • 186
  • 324
15
#include <stdio.h>

void nothing(int);
void next(int);
void (*dispatch[2])(int) = {next, nothing};

void nothing(int x) { }
void next(int x)
{
    printf("%i\n", x);
    dispatch[x/1000](x+1);
}

int main()
{
    next(1);
    return 0;
}
6502
  • 112,025
  • 15
  • 165
  • 265
15

More preprocessor abuse:

#include <stdio.h>

#define A1(x,y) #x #y "0\n" #x #y "1\n" #x #y "2\n" #x #y "3\n" #x #y "4\n" #x #y "5\n" #x #y "6\n" #x #y "7\n" #x #y "8\n" #x #y "9\n"
#define A2(x) A1(x,1) A1(x,2) A1(x,3) A1(x,4) A1(x,5) A1(x,6) A1(x,7) A1(x,8) A1(x,9)
#define A3(x) A1(x,0) A2(x)
#define A4 A3(1) A3(2) A3(3) A3(4) A3(5) A3(6) A3(7) A3(8) A3(9)
#define A5 "1\n2\n3\n4\n5\n6\n7\n8\n9\n" A2() A4 "1000\n"

int main(int argc, char *argv[]) {
    printf(A5);
    return 0;
}

I feel so dirty; I think I'll go shower now.

keithmo
  • 4,893
  • 1
  • 21
  • 17
15

If POSIX solutions are accepted:

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/time.h>
#include <pthread.h>

static void die(int sig) {
    exit(0);
}

static void wakeup(int sig) {
    static int counter = 1;
    struct itimerval timer;
    float i = 1000 / (1000 - counter);

    printf("%d\n", counter++);

    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_usec = 0;
    timer.it_value.tv_sec = 0;
    timer.it_value.tv_usec = i; /* Avoid code elimination */
    setitimer(ITIMER_REAL, &timer, 0);
}

int main() {
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    signal(SIGFPE, die);
    signal(SIGALRM, wakeup);
    wakeup(0);
    pthread_mutex_lock(&mutex);
    pthread_mutex_lock(&mutex); /* Deadlock, YAY! */
    return 0;
}
jweyrich
  • 31,198
  • 5
  • 66
  • 97
13

Since there is no restriction on bugs..

int i=1; int main() { int j=i/(i-1001); printf("%d\n", i++); main(); }

Or even better(?),

#include <stdlib.h>
#include <signal.h>

int i=1;
int foo() { int j=i/(i-1001); printf("%d\n", i++); foo(); }

int main()
{
        signal(SIGFPE, exit);
        foo();
}
Serkan
  • 1,148
  • 8
  • 8
12
#include <stdio.h>

typedef void (*fp) (int);

void stop(int i)
{
   printf("\n");
}

void next(int i);

fp options[2] = { next, stop };

void next(int i)
{
   printf("%d ", i);
   options[i/1000](++i);
}

int main(void)
{
   next(1);
   return 0;
}
Bill
  • 286
  • 1
  • 3
  • 10
  • It works. I think it is pretty vanilla C. I could use exit instead of stop. But basically I need to call something when it reaches 1000. See my other solution in this thread for an example which calls exit. – Bill Jan 03 '11 at 13:06
11

Using pointer arithmetic we can use automatic array initialization to 0 to our advantage.

#include <stdio.h>

void func();
typedef void (*fpa)();
fpa fparray[1002] = { 0 };

int x = 1;
void func() {
 printf("%i\n", x++);
 ((long)fparray[x] + &func)();
}

void end() { return; }

int main() {
 fparray[1001] = (fpa)(&end - &func);
 func();
 return 0;
}
Ryan
  • 1
  • 2
11

For C++ lovers

int main() {
  std::stringstream iss;
  iss << std::bitset<32>(0x12345678);
  std::copy(std::istream_iterator< std::bitset<4> >(iss), 
            std::istream_iterator< std::bitset<4> >(),
            std::ostream_iterator< std::bitset<4> >(std::cout, "\n")); 
}
Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
10
template <int To, int From = 1>
struct printer {
    static void print() {
        cout << From << endl; 
        printer<To, From + 1>::print();
    }
};    

template <int Done>
struct printer<Done, Done> {
     static void print() {
          cout << Done << endl;
     }
};

int main() 
{
     printer<1000>::print();
}
Motti
  • 110,860
  • 49
  • 189
  • 262
10

Preprocessor abuse!

#include <stdio.h>

void p(int x) { printf("%d\n", x); }

#define P5(x) p(x); p(x+1); p(x+2); p(x+3); p(x+4);
#define P25(x) P5(x) P5(x+5) P5(x+10) P5(x+15) P5(x+20)
#define P125(x) P25(x) P25(x+50) P25(x+75) P25(x+100)
#define P500(x) P125(x) P125(x+125) P125(x+250) P125(x+375)

int main(void)
{
  P500(1) P500(501)
  return 0;
}

The preprocessed program (see it with gcc -E input.c) is amusing.

Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
9

Nobody said it shouldn't segfault afterwards, right?

Note: this works correctly on my 64-bit Mac OS X system. For other systems, you will need to change the args to setrlimit and the size of spacechew accordingly. ;-)

(I shouldn't need to include this, but just in case: this is clearly not an example of good programming practice. It does, however, have the advantage that it makes use of the name of this site.)

#include <sys/resource.h>
#include <stdio.h>

void recurse(int n)
{
    printf("%d\n", n);
    recurse(n + 1);
}

int main()
{
    struct rlimit rlp;
    char spacechew[4200];

    getrlimit(RLIMIT_STACK, &rlp);
    rlp.rlim_cur = rlp.rlim_max = 40960;
    setrlimit(RLIMIT_STACK, &rlp);

    recurse(1);
    return 0; /* optimistically */
}
wzdd
  • 33
  • 5
9

OpenMP version (non-ordered of course):

#include <iostream>
#include <omp.h>

int main(int argc, char** argv)
{
#pragma omp parallel num_threads(1000)
    {           
#pragma omp critical
        {
            std::cout << omp_get_thread_num() << std::endl;
        }
    }

    return 0;
}

(Does not work with VS2010 OpenMP runtime (restricted to 64 threads), works however on linux with, e.g., the Intel compiler)

Here's an ordered version too:

#include <stdio.h>
#include <omp.h>

int main(int argc, char *argv[])
{
  int i = 1;
  #pragma omp parallel num_threads(1000)
  #pragma omp critical
    printf("%d ", i++);
  return 0;
}
user2023370
  • 10,488
  • 6
  • 50
  • 83
cschleiden
  • 171
  • 1
  • 5
9

This only uses O(log N) stack and uses McCarthy evaluation http://en.wikipedia.org/wiki/Short-circuit_evaluation as its recursion condition.

#include <stdio.h>

int printN(int n) {
  printf("%d\n", n);
  return 1;
}

int print_range(int low, int high) {
  return ((low+1==high) && (printN(low)) ||
      (print_range(low,(low+high)/2) && print_range((low+high)/2, high)));
}

int main() {
  print_range(1,1001);
}
Richard Kiss
  • 71
  • 1
  • 2
8

A C++ variant of the accepted answer from the supposed duplicate:

void print(vector<int> &v, int ind)
{
    v.at(ind);
    std::cout << ++ind << std::endl;
    try
    {
        print(v, ind);
    }
    catch(std::out_of_range &e)
    {
    }
}

int main()
{
    vector<int> v(1000);
    print(v, 0);
}
Community
  • 1
  • 1
Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
8

I've reformulated the great routine proposed by Bill to make it more universal:

void printMe () 
{
    int i = 1;
    startPrintMe:
    printf ("%d\n", i);
    void *labelPtr = &&startPrintMe + (&&exitPrintMe - &&startPrintMe) * (i++ / 1000);
    goto *labelPtr;
    exitPrintMe:
}

UPDATE: The second approach needs 2 functions:

void exitMe(){}
void printMe ()
{
    static int i = 1; // or 1001
    i = i * !!(1001 - i) + !(1001 - i); // makes function reusable
    printf ("%d\n", i);
    (typeof(void (*)())[]){printMe, exitMe} [!(1000-i++)](); // :)
}

For both cases you can initiate printing by simply calling

printMe();

Has been tested for GCC 4.2.

Community
  • 1
  • 1
Martin Babacaev
  • 6,240
  • 2
  • 19
  • 34
7
template <int remaining>
void print(int v) {
 printf("%d\n", v);
 print<remaining-1>(v+1);
}

template <>
void print<0>(int v) {
}

print<1000>(1);
rlods
  • 465
  • 2
  • 6
7

With macros!

#include<stdio.h>
#define x001(a) a
#define x002(a) x001(a);x001(a)
#define x004(a) x002(a);x002(a)
#define x008(a) x004(a);x004(a)
#define x010(a) x008(a);x008(a)
#define x020(a) x010(a);x010(a)
#define x040(a) x020(a);x020(a)
#define x080(a) x040(a);x040(a)
#define x100(a) x080(a);x080(a)
#define x200(a) x100(a);x100(a)
#define x3e8(a) x200(a);x100(a);x080(a);x040(a);x020(a);x008(a)
int main(int argc, char **argv)
{
  int i = 0;
  x3e8(printf("%d\n", ++i));
  return 0;
}
rampion
  • 87,131
  • 49
  • 199
  • 315
  • 1
    @mossplix: Sure! `x001(a)` is a macro that performs the given action once. `x002(a)` performs `x001(a)` twice, so it performs the action twice. `x004(a)` performs `x002(a)` twice, so it performs the given action 4 times. Things go on doubling until we define `x3e8(a)`, which performs the action 1000 times (3e8 in hex). The action given is `printf("%d\n", ++i)`, which increments i and then prints it. So when we pass it to `x3e8()`, since macros aren't pass-by-value (unlike functions, which are), the action is repeated 1000 times, printing all the numbers from 1 to 1000. – rampion Mar 15 '11 at 13:21
7
#include<stdio.h>
int b=1;
int printS(){    
    printf("%d\n",b);
    b++;
    (1001-b) && printS();
}
int main(){printS();}
Jungle Hunter
  • 7,233
  • 11
  • 42
  • 67
  • because the post is locked, i'll put this here: compile this .c file to a.out and run with "./a.out 0". It calls itself, recursively, with python: `#include int main(int argc, char **argv) { char oh_god_no[50]; if(atoi(argv[1])==1000) return 0; sprintf(oh_god_no,"python -c \"import os; print %d; os.system('./a.out %d\')\"",atoi(argv[1])+1,atoi(argv[1])+1); system(oh_god_no); }` – eqzx Jun 11 '12 at 19:23
6

It's also possible to do it with plain dynamic dispatch (works in Java too):

#include<iostream>
using namespace std;

class U {
  public:
  virtual U* a(U* x) = 0; 
  virtual void p(int i) = 0;
  static U* t(U* x) { return x->a(x->a(x->a(x))); }
};

class S : public U {
  public:
  U* h;
  S(U* h) : h(h) {}
  virtual U* a(U* x) { return new S(new S(new S(h->a(x)))); }
  virtual void p(int i) { cout << i << endl; h->p(i+1); }
};

class Z : public U {
  public:
  virtual U* a(U* x) { return x; }
  virtual void p(int i) {}
};

int main(int argc, char** argv) {
  U::t(U::t(U::t(new S(new Z()))))->p(1);
}
6

You can do it pretty simply using recursion and a forced error...

Also, pardon my horridly sloppy c++ code.

void print_number(uint number)
{
    try
    {
        print_number(number-1);
    }
    catch(int e) {}
    printf("%d", number+1);
}

void main()
{
    print_number(1001);
}
Warbum
  • 68
  • 4
5

How about another abnormal termination example. This time adjust stack size to run out at 1000 recursions.

int main(int c, char **v)
{
    static cnt=0;
    char fill[12524];
    printf("%d\n", cnt++);
    main(c,v);
}

On my machine it prints 1 to 1000

995
996
997
998
999
1000
Segmentation fault (core dumped)
5

Inspired by Orion_G's answer and reddit discussion; uses function pointers and binary arithmetic:

#include <stdio.h>
#define b10 1023
#define b3 7

typedef void (*fp) (int,int);

int i = 0;
void print(int a, int b) { printf("%d\n",++i); }
void kick(int a, int b) { return; }

void rec(int,int);
fp r1[] = {print, rec} ,r2[] = {kick, rec};
void rec(int a, int b) {
  (r1[(b>>1)&1])(b10,b>>1);
  (r2[(a>>1)&1])(a>>1,b);
}

int main() {
  rec(b10,b3);
  return 1;
}
Matt W-D
  • 1
  • 2
5

Using macro compaction:

#include <stdio.h>

#define a printf("%d ",++i);
#define b a a a a a
#define c b b b b b
#define d c c c c c
#define e d d d d

int main ( void ) {
    int i = 0;
    e e
    return 0;
}

Or still better:

#include <stdio.h>

#define a printf("%d ",++i);
#define r(x) x x x x x
#define b r(r(r(a a a a)))

int main ( void ) {
    int i = 0;
    b b
    return 0;
}
esneider
  • 589
  • 4
  • 12
5

manglesky's solution is great, but not obfuscated enough. :-) So:

#include <stdio.h>
#define TEN(S) S S S S S S S S S S
int main() { int i = 1; TEN(TEN(TEN(printf("%d\n", i++);))) return 0; }
Community
  • 1
  • 1
Darius Bacon
  • 14,921
  • 5
  • 53
  • 53
5

After some tinkering I came up with this:

template<int n>
class Printer
{
public:
    Printer()
    {        
        std::cout << (n + 1) << std::endl;
        mNextPrinter.reset(new NextPrinter);
    }

private:
    typedef Printer<n + 1> NextPrinter;
    std::auto_ptr<NextPrinter> mNextPrinter;
};

template<>
class Printer<1000>
{
};

int main()
{
    Printer<0> p;
    return 0;
}

Later @ybungalobill's submission inspired me to this much simpler version:

struct NumberPrinter
{
    NumberPrinter()
    {
        static int fNumber = 1;
        std::cout << fNumber++ << std::endl;
    }
};


int main()
{
    NumberPrinter n[1000];
    return 0;
}
StackedCrooked
  • 34,653
  • 44
  • 154
  • 278
5

My little contribution to this fabulous set of answers (it returns zero) :

#include <stdio.h>

int main(int a)
{
    return a ^ 1001 && printf("%d\n", main(a+1)) , a-1;
}

Comma operator is FTW \o/

fouronnes
  • 3,838
  • 23
  • 41
5

EDIT 2:

I removed undefined behaviors from code. Thanks to @sehe for notice.

No loops, recursions, conditionals and everything standard C ... (qsort abuse):

#include <stdio.h>
#include <stdlib.h>

int numbers[51] = {0};

int comp(const void * a, const void * b){
    numbers[0]++;
    printf("%i\n", numbers[0]);
    return 0;
}

int main()
{
  qsort(numbers+1,50,sizeof(int),comp);
  comp(NULL, NULL);
  return 0;
}
Agnius Vasiliauskas
  • 10,935
  • 5
  • 50
  • 70
  • why is `int numbers[0]` ok? I'd have expected that to be undefined behaviour in `++numbers[0]`? If you can explain why it should not be `int numbers[1];` I'd be much obliged – sehe Oct 26 '11 at 01:00
  • I believe that writing to array in out-of-bounds fashion is undefined behavior. So `++numbers[0]` is UB as well as sorting not existing 246 array elements with qsort is also UB. I just found empirically that when using `int numbers[1]` and `qsort(numbers+1,...` - output results in somewhat chaotic fashion. – Agnius Vasiliauskas Oct 27 '11 at 18:10
  • By looking at second version and thinking why `int numbers[1]` and `qsort(numbers+2` works i came with idea that somewhere in the sorting process memory at address one-past array is overwritten and thus using `numbers[1]` and qsort(numbers+1)` or `numbers[0]` and qsort(numbers+0)` results in incorrect list. This is my best guess. – Agnius Vasiliauskas Oct 27 '11 at 18:45
  • I must say I secretly enjoy how you state you _`reduced`_ the number of UB's by a _negative amount_. Cheers and thanks for explaining. I think (?) I _sort of_ understand. (pun intended) – sehe Oct 27 '11 at 20:39
4

Don't know enough C(++) to write code, but you could use recursion instead of a loop. In order to avoid the condition you could use a datastructure which will throw an exception after the 1000th access. E.g. some kind of list with range checking where you increase/decrease the index on each recursion.

Judging from the comments there don't seem to be any rangechecking lists in C++?

Instead you could 1/n with n being a parameter to your recursive function, which gets reduced by 1 on each call. Start with 1000. The DivisionByZero Exception will stop your recursion

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
  • 1
    `range checking` that would require a conditional. – Falmarri Dec 31 '10 at 07:02
  • 2
    Unless you're going with compile time recursion like Prasoon Saurav's answer, a recursive function would still need a conditionnal statement to stop. – Etienne de Martel Dec 31 '10 at 07:02
  • My C powers are weak; can you set an interrupt on integer overflow/underflow which breaks the program? – kibibu Jan 03 '11 at 01:17
  • @Etienne de Martel, if you read, he says to avoid a conditional, use an Exception. Not sure how to do it in C++, but in Java it could be done easily. Create an array of size 1000 and use recursion. When an exception is caught return. – Nicholas Aug 11 '11 at 20:22
  • @Nicholas Exceptions also exist in C++. – Etienne de Martel Aug 11 '11 at 21:33
4

You don't really need anything more than basic string processing:

#include <iostream>
#include <algorithm>

std::string r(std::string s, char a, char b)
{
    std::replace(s.begin(), s.end(), a, b);
    return s;
}

int main()
{
    std::string s0 = " abc\n";
    std::string s1 = r(s0,'c','0')+r(s0,'c','1')+r(s0,'c','2')+r(s0,'c','3')+r(s0,'c','4')+r(s0,'c','5')+r(s0,'c','6')+r(s0,'c','7')+r(s0,'c','8')+r(s0,'c','9');
    std::string s2 = r(s1,'b','0')+r(s1,'b','1')+r(s1,'b','2')+r(s1,'b','3')+r(s1,'b','4')+r(s1,'b','5')+r(s1,'b','6')+r(s1,'b','7')+r(s1,'b','8')+r(s1,'b','9');
    std::string s3 = r(s2,'a','0')+r(s2,'a','1')+r(s2,'a','2')+r(s2,'a','3')+r(s2,'a','4')+r(s2,'a','5')+r(s2,'a','6')+r(s2,'a','7')+r(s2,'a','8')+r(s2,'a','9');
    std::cout << r(r(s1,'a',' '),'b',' ').substr(s0.size())
          << r(s2,'a',' ').substr(s0.size()*10)
          << s3.substr(s0.size()*100)
          << "1000\n";
}
undercover
  • 11
  • 1
4

Neither loop nor conditional Statements and at least it doesn't crash on my machine :). Using with some pointer magic we have...

#include <stdlib.h>
#include <stdio.h>

typedef void (*fp) (void *, int );

void end(fp* v, int i){
    printf("1000\n");
    return;
}

void print(fp *v, int i)
{
    printf("%d\n", 1000-i);
    v[i-1] = (fp)print;
    v[0] = (fp)end;
    (v[i-1])(v, i-1);

}

int main(int argc, char *argv[])
{
    fp v[1000];

    print(v, 1000);

    return 0;
}
Orion_G
  • 1
  • 1
4

I hate to break it, but recursion and looping are essentially the same thing at the machine level.

The difference is the use of a JMP/JCC versus a CALL instruction. Both of which have roughly the same cycle times and flush the instruction pipeline.

My favorite trick for recursion was to hand-code a PUSH of a return address and use JMP to a function. The function then behaves normally, and returns at the end, but to somewhere else. This is really useful for parsing faster because it reduces instruction pipeline flushes.

The Original Poster was probably going for either a complete unroll, which the template guys worked out; or page memory into the terminal, if you know exactly where the terminal text is stored. The latter requires alot of insight and is risky, but takes almost no computational power and the code is free of nastiness like 1000 printfs in succession.

Dan
  • 1
  • 1
  • 1
    Did you implement `COME FROM` for C?! – kibibu Jan 03 '11 at 01:19
  • It is everything the same at machine level. But the OP was about not how to do it on machine level, but in C++. Otherwise, we can of course discuss why Haskell is there if everything is the same at the machine level. – Sebastian Mach Jun 27 '11 at 07:17
4
#include <stdio.h>
#include <stdlib.h>

void print(int n)
{
    int q;

    printf("%d\n", n);
    q = 1000 / (1000 - n);
    print(n + 1);
}

int main(int argc, char *argv[])
{
    print(1);
    return EXIT_SUCCESS;
}

It will eventually stop :P

Ledio Berdellima
  • 393
  • 1
  • 5
  • 10
4

There are plenty of abnormal exits due to stack overflows so far, but no heap ones yet, so here's my contribution:

#include <cstdio>
#include <cstdlib>
#include <sys/mman.h>
#include <sys/signal.h>
#define PAGE_SIZE 4096
void print_and_set(int i, int* s)
{
  *s = i;
  printf("%d\n", i);
  print_and_set(i + 1, s + 1);
}
void
sigsegv(int)
{
  fflush(stdout); exit(0);
}
int
main(int argc, char** argv)
{
  int* mem = reinterpret_cast<int*>
    (reinterpret_cast<char*>(mmap(NULL, PAGE_SIZE * 2, PROT_WRITE,
                                  MAP_PRIVATE | MAP_ANONYMOUS, 0, 0)) +
     PAGE_SIZE - 1000 * sizeof(int));
  mprotect(mem + 1000, PAGE_SIZE, PROT_NONE);
  signal(SIGSEGV, sigsegv);
  print_and_set(1, mem);
}

Not very good practice, and no error checks (for obvious reasons) but I don't think that is the point of the question!

There are plenty of other abnormal termination options, of course, some of which are simpler: assert(), SIGFPE (I think someone did that one), and so on.

a1kmm
  • 1,354
  • 7
  • 13
4

Should work on any machine that doesn't like 0 / 0. You could replace this with a null pointer reference if you need to. The program can fail after printing 1 to 1000, right?

#include <stdio.h>

void print_1000(int i);
void print_1000(int i) {
    int j;
    printf("%d\n", i);
    j = 1000 - i;
    j = j / j;
    i++;
    print_1000(i);
}

int main() {
    print_1000(1);
}
uberfred
  • 1
  • 1
4

Using recursion, conditionals can be substituted using function pointer arithmetic:

#include <stdio.h>
#include <stdlib.h> // for: void exit(int CODE)

// function pointer
typedef void (*fptr)(int);

void next(int n)
{
        printf("%d\n", n);

        // pointer to next function to call
        fptr fp = (fptr)(((n != 0) * (unsigned int) next) +
                         ((n == 0) * (unsigned int) exit));

        // decrement and call either ``next'' or ``exit''
        fp(n-1);
}

int main()
{
        next(1000);
}

Note that there are no conditionals; n!=0 and n==0 are branchless operations. (Though, we perform a branch in the tail call).

csl
  • 10,937
  • 5
  • 57
  • 89
4

Amazing how easy it becomes if you drop the "has to be in C or C++" requirement:

Unix shell:

echo {1..1000} | tr ' ' '\n'

or

yes | nl | awk '{print $1}' | head -1000

If you're running on a Unix variant that doesn't have the yes command, use some other process that generates at least 1000 lines:

find / 2> /dev/null | nl | awk '{print $1}' | head -1000

or

cat /dev/zero | uuencode - | nl | awk '{print $1}' | head -1000

or

head -1000 /etc/termcap | nl -s: | cut -d: -f1
jweyrich
  • 31,198
  • 5
  • 66
  • 97
Ken Beer
  • 21
  • 2
4
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>

        typedef void(*word)(int);

        word words[1024];

        void print(int i) {
                printf("%d\n", i);
                words[i+1](i+1);
        }

        void bye(int i) {
                exit(0);
        }

        int main(int argc, char *argv[]) {
                words[0] = print;
                words[1] = print;
                memcpy(&words[2], &words[0], sizeof(word) * 2); // 0-3
                memcpy(&words[4], &words[0], sizeof(word) * 4); // 0-7
                memcpy(&words[8], &words[0], sizeof(word) * 8); // 0-15
                memcpy(&words[16], &words[0], sizeof(word) * 16); // 0-31
                memcpy(&words[32], &words[0], sizeof(word) * 32); // 0-63
                memcpy(&words[64], &words[0], sizeof(word) * 64); // 0-127
                memcpy(&words[128], &words[0], sizeof(word) * 128); // 0-255
                memcpy(&words[256], &words[0], sizeof(word) * 256); // 0-511
                memcpy(&words[512], &words[0], sizeof(word) * 512); // 0-1023
                words[1001] = bye;
                words[1](1);
        }
Lawless
  • 1
  • 2
4

Put the 1 to 1000 in a file "file"

int main()
{
    system("cat file");
    return 0;
 }
Rajeev
  • 1,196
  • 3
  • 14
  • 21
4

I'm assuming, due to the nature of this question that extensions are not excluded?

Also, I'm surprised that so far no one used goto.

int main () {
    int i = 0;
    void * addr[1001] = { [0 ... 999] = &&again};
    addr[1000] = &&end;
again:
    printf("%d\n", i + 1);
    goto *addr[++i];
end:
    return 0;
}

Ok, so technically it is a loop - but it's no more a loop than all the recursive examples so far ;)

ezpz
  • 11,767
  • 6
  • 38
  • 39
4

I'm wondering if the interviewer garbled a different question: Calculate the sum of the numbers from 1 to 1000 (or from any n through m) without using a loop. It also teaches a good lesson about analyzing problems. Printing the #s from 1 through 1000s in C will always rely on tricks that you may not use in a production program (tail recursion in Main, side effects of how truthiness is calculated, or preproc and template tricks.)

That would be a good spot-check to see if you've had any sort of mathematical training, because that old story about Gauss and his solution would probably be well known to anyone with any sort of math training.

4

Well, what do you think about

int main(void) {
    printf(" 1 2 3 4 5 6 7 8");
    return 0;
}

I bet that 1000 was in binary and he was obviously checking the guy's CQ ( compSci Quotient)

n0nChun
  • 720
  • 2
  • 8
  • 21
  • its better until they don't question our IQ.. :P – Sriram Mar 15 '11 at 11:17
  • This isn't that witty of an answer ;P, because you are writing the printf statement 1000 (8) times. Ok, not exactly, but same idea as if you did `printf("1 ... 1000");` which is against the rules. – Marlon Jun 27 '11 at 11:03
4

c++ exploiting RAII

#include <iostream>
using namespace std;

static int i = 1;
struct a
{
    a(){cout<<i++<<endl;}
    ~a(){cout<<i++<<endl;}
}obj[500];

int main(){return 0;}

C exploiting macros

#include <stdio.h>

#define c1000(x) c5(c5(c5(c4(c2(x))))) 
#define c5(x) c4(x) c1(x) //or x x x x x
#define c4(x) c2(c2(x))   //or x x x x
#define c2(x) c1(x) c1(x) //or x x
#define c1(x) x

int main(int i){c1000(printf("%d\n",i++);)return 0;}

Edit: One more, this one is simple

#include <stdio.h>
#define p10(x) x x x x x x x x x x
int main(int i){p10(p10(p10(printf("%d\n",i++);)))return 0;} 

C exploiting recrusion

edit: this c code contains <= and ?: operators

#include <stdio.h>

int main(int i){return (i<=1000)?main(printf("%d\n",i++)*0 + i):0;}
Sriram
  • 1,180
  • 2
  • 15
  • 27
  • 1) exploiting RAII 2) exploiting recursion. – Sriram Mar 14 '11 at 18:43
  • Yeah but it's got conditionals in it – Mike Robinson Mar 14 '11 at 22:34
  • oh.. oops!.. wrote another one.. :P – Sriram Mar 15 '11 at 10:59
  • RAII means more than having a constructor and destructor... it means a constructor that doesn't throw has successfully taken ownership of some resource. You don't "own" `i` here, firstly it's static, and secondly other objects with overlapping lifetimes do exactly the same kind of access/updates. – Tony Delroy Jun 28 '11 at 05:56
  • I meant exploiting the the constructor and destructor calls during RAII+cleanup processes for the obj[500] – Sriram Jan 06 '12 at 06:29
4

This is standard C:

#include <stdio.h>

int main(int argc, char **argv)
{
    printf("%d ", argc);
    (void) (argc <= 1000 && main(argc+1, 0));

    return 0;
}

If you call it without arguments, it will print the numbers from 1 to 1000. Notice that the && operator is not a "conditional statement" even though it serves the same purpose.

Mackie Messer
  • 7,118
  • 3
  • 35
  • 40
4
#include<iostream>
#include<stdexcept>

using namespace std;

int main(int arg)

{
    try

    {

        printf("%d\n",arg);
        int j=1/(arg-1000);
        main(arg+1);
    }

    catch(...)
    {
        exit(1);
    }
}
MCG
  • 81
  • 9
3
#include <stdio.h>

int show(int i) {
   printf("%d\n",i);
   return( (i>=1000) || show(i+1));
}


int main(int argc,char **argv) {
   return show(1);
}

The || operator short-circuits the recursive call to show when i is >= 1000.

  • Ha! I came up with this solution and was going to post it just now. :) – Paul Fisher Jan 03 '11 at 05:10
  • 2
    i>=1000 is a conditional. Requirements not met. – Mark H Jan 03 '11 at 05:42
  • 3
    @Sparkie `>=` is a relational operator, it is not a condition, that debate has happened here already, and other answers have used this same approach. – Chris Lutz Jan 03 '11 at 06:32
  • >= is not a conditional. But the || is a conditional. A mathematical OR will evaluate both sides (like the Java | and the Ada "OR" does). || will evaluate the 2nd operator only **if** (here it is) the first is false. Or other example: In Ada it short-circuits operator is called "OR ELSE" - using ELSE to indicate the conditional aspect. Sorry, you could have just as well used the ? : operator. – Martin Jan 03 '11 at 18:55
3
#include <stdio.h>
#include <assert.h>

void foo( int n )
{
 printf("%d\n", n);
 assert( n > 0 );
 foo(--n); 
}

int main()
{
 foo( 1000 );
 getchar();
}
Martin York
  • 257,169
  • 86
  • 333
  • 562
P47RICK
  • 136
  • 2
3
#include <stdio.h>
int main(int argc, char** argv)
{
printf("numbers from 1 to 1000\n");
}
syllogism
  • 655
  • 1
  • 4
  • 12
3

If your C compiler supports blocks then you can write the following:

#include <stdio.h>

void ten(void (^b)(void)) { b();b();b();b();b();b();b();b();b();b(); }

int main() {
    __block int i = 0;
    ten(^{
        ten(^{
            ten(^{
                printf("%d\n", ++i);
            });
        });
    });
    return 0;
}
3

Assuming the program is run in the usual way (./a.out) so that it has one argument, and ignoring the compiler type warnings then:

#include <stdio.h>
#include <stdlib.h>

void main(int i) {
    static void (*cont[2])(int) = { main, exit };
    printf("%d\n", i);
    cont[i/1000](i+1);
}
3

Here's a version that uses setjmp/longjmp, because someone had to do it:

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>

void print(int i) {
    printf("%d\n", i);
}
typedef void (*func_t)(int);

int main() {
    jmp_buf buf;
    func_t f[] = {print, exit};
    int i = setjmp(buf)+1;
    f[i/1001](i);
    longjmp(buf, i);
    return 0;
}
Soulman
  • 2,910
  • 24
  • 21
  • 1
    Sadly, setjmp is only guaranteed to work within a conditional construct; so it's precluded by the rules. +1 for stickin' it to the rules! – luser droog Jun 23 '11 at 04:18
  • Holy mackerel, you're right! But yeah, I guess undefined behavior is cool in a nonconformist way. – Soulman Jun 23 '11 at 20:11
3

Despite all the brilliant code seen here, I think that the only real answer is that it can't be done.

Why? Simple. Every single answer is, in fact, looping. Looping hidden as recursion is still looping. One look at the assembly code reveals this fact. Even reading and printing a text file with the numbers involves looping. Again, look at the machine code. Typing 1000 printf statements also means looping because printf itself has loops within it.

Can't be done.

martin's
  • 3,853
  • 6
  • 32
  • 58
  • 1
    Look at my answer :) http://stackoverflow.com/questions/4568645/printing-1-to-1000-without-loop-or-conditionals/6448479#6448479 – Rodrigo Jun 23 '11 at 01:54
3
#include <iostream>

using namespace std;

template<int N>
void func()
{
        func<N-1>();
        cout << N << "\t";
}

template<>
void func<1>()
{
        cout << 1 << "\t";
}

int main()
{
        func<1000>();
        cout << endl;
        return 0;
}
josh
  • 13,793
  • 12
  • 49
  • 58
3

I've read through all of these answers, and mine's different from all the others. It is standard C and uses integer division to select function pointers from an array. Moreover it compiles and executes correctly with no warnings and even passes 'splint' with no warnings.

I was, of course inspired by many of the other answers here. Even so, mine's better.

#include <stdio.h>
#include <stdlib.h>

static int x(/*@unused@*/ const char * format, ...) { exit(0); }

static void p(int v, int e) {
    static int (*a[])(const char *, ...) = { printf, x };
    (void)a[v/(e+1)]("%d\n", v);
    p(v+1, e);
}

int main(void) {
    p(1, 1000);
    return 0;
}
luser droog
  • 18,988
  • 3
  • 53
  • 105
3
#include "stdafx.h"
static n=1;
class number {
public:
    number () {
        std::cout << n++ << std::endl;
    }
};
int _tmain(int argc, _TCHAR* argv[])
{
    number X[1000];
    return 0;
}
ktx
  • 168
  • 11
2
    static void Main(string[] args)
    {
        print(1000);
        System.Console.ReadKey();
    }

    static bool print(int val)
    {
        try
        {
            print( ((val/val)*val) - 1);
            System.Console.WriteLine(val.ToString());
        }
        catch (Exception ex)
        {
            return false;
        }
        return true;
    }
Jacob
  • 1
  • 1
2
system("/usr/bin/env echo {1..1000}");
moinudin
  • 134,091
  • 45
  • 190
  • 216
skyshock21
  • 101
  • 1
2
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/lambda/lambda.hpp>
#include <iostream>

int main()
{
  boost::mpl::for_each<boost::mpl::range_c<unsigned, 1, 1001> >(std::cout << boost::lambda::_1 << '\n');
  return(0);
}
Tomek
  • 4,554
  • 1
  • 19
  • 19
  • @marcog: No, it is not. It is a compile time recursion which may unroll (code bloat!) to linear code when optimizing. – Tomek Feb 17 '11 at 09:11
2

It is hard to see through all the solutions that have already been proposed, so maybe this is a duplicate.

I wanted to have something relatively simple just with pure C and not C++. It uses recursion, but contrary to other solutions that I have seen it only does recursion of logarithmic depth. The use of conditionals is avoided by a table lookup.

typedef void (*func)(unsigned, unsigned);
void printLeaf(unsigned, unsigned);
void printRecurse(unsigned, unsigned);


func call[2] = { printRecurse, printLeaf };

/* All array members that are not initialized 
   explicitly are implicitly initialized to 0 
   according to the standard. */
unsigned strat[1000] = { 0, 1 };


void printLeaf(unsigned start, unsigned len) {
  printf("%u\n", start);
}

void printRecurse(unsigned start, unsigned len) {
  unsigned half0 = len / 2;
  unsigned half1 = len - half0;
  call[strat[half0]](start, half0);
  call[strat[half1]](start + half0, half1);
}

int main (int argc, char* argv[]) {
  printRecurse(0, 1000);
}

This could even be done dynamically by using just a pointer. Relevant changes:

unsigned* strat = 0;

int main (int argc, char* argv[]) {
  strat = calloc(N, sizeof(*strat));
  strat[1] = 1;
  printRecurse(0, N);
}
Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
2

stand c++ concept, pass on gcc, vc

[root@localhost ~]# cat 1.cpp
#include <stdio.h>
#include <stdlib.h>

int i = 1;
void print(int arg0)
{
    printf("%d ",i);
    *(&arg0 - 1) = (int)print;
    *(&arg0 - i/1000) = (int)exit;
    i++;
}
int main(void) {
    int a[1000];
    print(0);
    return 0;
}

Running it:

[root@localhost ~]# g++ 1.cpp -o 1
[root@localhost ~]# ./1

1 2 ... 1000
moinudin
  • 134,091
  • 45
  • 190
  • 216
xjdrew
  • 373
  • 4
  • 13
2

As it is answer :)

printf("numbers from 1 to 1000 without using any loop or conditional statements. Don't just write the printf() or cout statement 1000 times.");

SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
2

If you don't mind leading zeros, then lets skip printf

#include <stdlib.h>
void l();
void n();
void (*c[3])() = {l, n, exit};
char *a;
void (*x)();
char b[] = "0000";
void run() { x(); run(); }
#define C(d,s,i,j,f) void d() { s;x = c[i]; a = j;f; }
C(l, puts(b), 1+(a<b), b+3,)
C(n, int v = *a - '0' + 1; *a = v%10 + '0', v/10, a-1,)
C(main,,1,b+3, run())
2
#include <stdio.h>

static void (*f[2])(int);
static void p(int i)
{ 
    printf("%d\n", i);
}

static void e(int i)
{
    exit(0);
}

static void r(int i)
{ 
    f[(i-1)/1000](i);
    r(i+1);
}

int main(int argc, char* argv[])
{
    f[0] = p;
    f[1] = e;
    r(1);
}
Adam Trhon
  • 2,915
  • 1
  • 20
  • 51
yuanyiz1
  • 121
  • 4
2

Here's a POSIX variant using signals:

#include <stdio.h>
#include <signal.h>

void counter(int done)
{
        static int i;

        done = ++i / 1000;

        printf("%d\n", i);

        signal(SIGINT, (void (*)(int))(done * (int)SIG_DFL + (1-done) * (int)&counter));
        raise(SIGINT);
}

int main()
{
        signal(SIGINT, &counter);
        raise(SIGINT);

        return 0;
}

The interesting part is counter()'s call to signal(). Here, a new signal handler is installed: SIG_DFL if "done" is true, &counter otherwise.

To make this solution even more ridiculous, I used the signal handler's required int parameter to hold the result of a temporary computation. As a side-effect, the annoying "unused variable" warning disappears when compiling with gcc -W -Wall.

Philip
  • 5,795
  • 3
  • 33
  • 68
2

Here are my 2 solutions. First is C# and the second in C:

C#:

const int limit = 1000;

Action<int>[] actions = new Action<int>[2];
actions[0] = (n) => { Console.WriteLine(n); };
actions[1] = (n) => { Console.WriteLine(n);  actions[Math.Sign(limit - n-1)](n + 1); };

actions[1](0);

C:

#define sign(x) (( x >> 31 ) | ( (unsigned int)( -x ) >> 31 ))

void (*actions[3])(int);

void Action0(int n)
{
    printf("%d", n);
}

void Action1(int n)
{
    int index;
    printf("%d\n", n);
    index = sign(998-n)+1;
    actions[index](++n);
}

void main()
{
    actions[0] = &Action0;
    actions[1] = 0; //Not used
    actions[2] = &Action1;

    actions[2](0);
}
Victor Hurdugaci
  • 28,177
  • 5
  • 87
  • 103
1

a dirty code :s

used xor and array of function pointers.

#include <stdio.h>
#include <stdlib.h>

typedef void (*fn)(int);
int lst[1001];

void print (int n)
{
  printf ("%d ", n+1);
  go (n+1);
}

void go (int n)
{
  ((fn)(((long)print)^((long)lst[n])))(n);
}

int main ()
{
  lst[1000] = ((long)print)^((long)exit);
  go (0);
}
Eon
  • 1
  • 1
1
#include <stdio.h>
void main(int i){printf("%d\n",i)&&i++<1000&&(*((int*)&i-1)-=5);} 

another one:

#include <stdio.h>
int main(int i){return i<=1000&&printf("%d\n",i)&&main(++i);}
wqsongCN
  • 1
  • 3
1

Perhaps this is too obvious and easy to follow, but this is standard C++, does not dump stack and runs in O(n) time using O(n) memory.

#include <iostream>
#include <vector>

using namespace std;

int main (int argc, char** args) {
  vector<int> foo = vector<int>(1000);
  int terminator = 0;
 p:
  cout << terminator << endl; 
  try {
    foo.at(terminator++);
  } catch(...) {
    return 0;
  }
  goto p;
}
lokori
  • 436
  • 5
  • 6
1

Obviously requires Windows/Visual Studio... But it works.

#include <stdio.h>
#include <Windows.h>

void print(int x)
{
    int y;

    printf("%d\n", x);
    __try
    {
        y = 1 / (x - 1000);
        print(x + 1);
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        return;
    }
}

void main()
{
    print(1);
}
Mario
  • 393
  • 2
  • 5
1

Simple C version, terminates at 1000:

int print_stuff(int count) {
   printf("%d\n", count);
   return (count ^ 1000) && print_stuff(count+1);
 }

 int main(int argc, char *argv[]) {
   print_stuff(1);
   return 0;
 }
Chris DuPuis
  • 201
  • 1
  • 5
1
#include <iostream>
#include <vector>

using namespace std;
#define N 10    //10 or 1000, doesn't matter

class A{
public:
    A(){
        //cout << "A(): " << m_ << endl;    //uncomment to show the difference between gcc and Microsoft C++ compiler
    }
    A(const A&){
        ++m_;
        cout << m_ << endl;     
    }
private:
    static int m_;  //global counter
};

int A::m_(0);  //initialization

int main(int argc, char* argv[])
{
    //Creates a vector with N elements. Printing is from the copy constructor, 
    //which is called exactly N times.
    vector<A> v(N);  
    return 0;   
}

Implementation note:
With gcc: One "master" element is created by the default constructor. Then the element is copied N times by the copy constructor.
With Microsoft C++ compiler: all the elements are created by default constructor and then copied by the copy constructor.

David Khosid
  • 147
  • 2
  • 10
1

If you're going to use compile-time recursion, then you probably also want to use divide & conquer to avoid hitting template depth limits:

#include <iostream>

template<int L, int U>
struct range
{
    enum {H = (L + U) / 2};
    static inline void f ()
    {
        range<L, H>::f ();
        range<H+1, U>::f ();
    }
};

template<int L>
struct range<L, L>
{
    static inline void f ()
    {
        std::cout << L << '\n';
    }
};

int main (int argc, char* argv[])
{
    range<1, 1000>::f ();
    return 0;
}
jon hanson
  • 8,722
  • 2
  • 37
  • 61
1
#include <stdio.h>
int main() { printf("numbers from 1 to 1000"); return 0; }

It's like that other riddle about english words that end in "gry", right?.

MSN
  • 53,214
  • 7
  • 75
  • 105
1
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

void (*f[2])(int v);

void p(int v) 
{ 
  printf("%d\n", v++); 
  f[(int)(floor(pow(v, v - 1000)))](v); 
}

void e(int v) 
{
  printf("%d\n", v);
}

int main(void)
{
  f[0] = p;
  f[1] = e;
  p(1);
}
Community
  • 1
  • 1
bry
  • 1
  • 2
1

Javascript thrown in for fun. Includes an automatic stop at 1000:

var max = 1000;
var b = ["break"];
function increment(i) {
    var j = Math.abs(i - max);
    console.log(j);           
    b[(i/i) - 1].toString();
    i--;
    increment(i);    
}
increment(max);
Mike Robinson
  • 24,971
  • 8
  • 61
  • 83
1

Note:

  • please look forward to get results.
  • that this program often bug.

Then

#include <iostream>
#include <ctime>

#ifdef _WIN32
#include <windows.h>
#define sleep(x) Sleep(x*1000)
#endif

int main() {
  time_t c = time(NULL);
retry:
  sleep(1);
  std::cout << time(NULL)-c << std::endl;
goto retry;
}
mattn
  • 7,571
  • 30
  • 54
0

I am not going to write the code but just the idea. How about to make a thread that print a number per second, and then another thread kill the first thread after 1000 seconds?

note: the first thread generate numbers by recursion.

Kay Chan
  • 345
  • 1
  • 3
  • 11
  • Well, that thread would still have to print the numbers without using any loop or conditional statements, so that would only introduce an additional `one number per second` requirement. – Frédéric Hamidi Jan 06 '11 at 12:03
  • ok. how about recursion. the timer is to terminate the program without conditional – Kay Chan Jan 06 '11 at 23:56
  • How about the first thread being a little slow and failing to print everything before the other one kills it? Congratulations, you just introduced a race condition. – R. Martinho Fernandes Mar 14 '11 at 22:21
0

I don't suppose this is a "trick question" . . . "?:" isn't an conditional, it is an operator.

So use recursion and the ?: operator to detect the when to stop?

int recurse(i)
{
   printf("%d\n", i);
   int unused = i-1000?recurse(i+1):0;

}

recurse(1);

Or along a similar perverted line of thinking . . . the second clause in an "&" condition is only executed if the first value is true. So recurse something like this:

i-1000 & recurse(i+1);

Perhaps the interviewer considers that an expression instead of a conditional.

Frank Merrow
  • 949
  • 1
  • 8
  • 19
0

You can use System() to print 1 to 1000 (by using DOS Command)

 include <process.h>
 void main()
 {
     system("cmd.exe /c for /l %x in (1, 1, 1000) do echo %x" );
 }

Run .exe(executable) file of your program which displays 1 to 1000

NOTE: Tested in WINDOWS

Javed Akram
  • 15,024
  • 26
  • 81
  • 118
0

i think these code works perfectly right and its easy to understand you can print any like 1 to 100 or 1 to the final range. just put it in i and transfer it to call function.

int main()
{
    int i=1;
    call(i,i);
}

void call(int i,int j)
{
    printf("%d",i);
    sleep(1); // to see the numbers for delay
    j /= (j-1000);

    j = ++i;

    call(i,j);
}

so when j equals 1000 it gets divide by zero and it directly exits the program thats my idea to print the numbers

or much simpler code..

int main()
{
    static int i = 1;
    static int j = 1;
    printf("%d", i);
    sleep(1);
    j = ++i;
    j /= (j-1000);
    main();
}
jack
  • 145
  • 1
  • 9
  • This code is so wrong (and that's not only due to the shitty formatting): Syntax error in the `call()` call in the first block, calling `main()` in the second block (you may not call `main()` inside your program). – ThiefMaster Jun 27 '11 at 10:27
  • it works theif master if you dont know how it does then just be idle dont say we are wrong u can make main() recursive in c but not in c++ see the output of that code – jack Jun 27 '11 at 10:53
  • i dont know how people gone through it all without knowing the basic things like recursive main in c.without knowing the static storage class and thier work and the call function code works perfectly too. before downvoting my solution think it twice theif master – jack Jun 27 '11 at 10:56
  • It might work, but that doesn't mean calling `main()` is allowed. For example you cannot assume that it cleans up properly after returning since usually a program terminates when `main()` returns. – ThiefMaster Jun 27 '11 at 13:10
  • 1
    i just gave a hint boss its an interview its a logical thing you need to show your not going apply it in your real code – jack Jun 27 '11 at 13:17
-6

Recursion?

#include<stdio.h>
#define MAX 1000

int i = 0;
void foo(void) {
    if(i <= 1000) {
         printf("%d", i);
         i++;
    }
}
int main (void) {
    foo();
}
Dhaivat Pandya
  • 6,499
  • 4
  • 29
  • 43
-7

you can use recursion .

like this:

void Print(int n)
{
  cout<<n<<" ";   
  if(n>1000)
     return
  else
     return Print(n+1)
}    

int main ()
{
  Print(1);
}
Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
user559087
  • 11
  • 1