322
votes

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++?

35
  • 137
    The obvious answer is to use 500 calls to printf and print two numbers each time, no? Dec 31, 2010 at 6:59
  • 433
    printf("numbers from 1 to 1000"); Dec 31, 2010 at 7:07
  • 7
    :? isn't a conditional statement (it's an expression)...
    – Chris Lutz
    Dec 31, 2010 at 9:48
  • 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, 2010 at 18:40
  • 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. Dec 31, 2010 at 23:17

106 Answers 106

1194
votes

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);
}
24
  • 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 3, 2011 at 19:34
  • 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 :) Jan 4, 2011 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 4, 2011 at 22:06
  • 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. Jan 17, 2011 at 10:03
  • 9
    Yeah, yeah, it's not strictly legal C++ code for the reasons @ybungalobill gives, but I have to +1 for sheer insanity and the fact that it does compile and work on a few platforms. There are times when the correct response to "But it's not standard!" is "Who cares!" :) Jan 26, 2011 at 8:26
784
votes
+100

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);
}
32
  • 8
    Can somebody explain to me how this works? pretty impressive.
    – gath
    Jan 3, 2011 at 5:18
  • 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 3, 2011 at 11:49
  • 42
    For those curious enough to compile this: in g++, set -ftemplate-depth-1000. The default template recursion maximum is 500.
    – Tom
    Jan 3, 2011 at 18:47
  • 6
    This still uses conditionals: pattern matching is a glorified if.
    – David K.
    Jan 4, 2011 at 6:33
  • 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, 2011 at 23:43
544
votes
#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.

4
  • 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 3, 2011 at 6: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. Jan 3, 2011 at 8:44
  • Oh yeah, I see Keith's answer does generate the whole string, cool. :) I missed that. Jan 3, 2011 at 8: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 Apr 11, 2011 at 10:08
298
votes

Looks like it doesn't need to use loops

printf("1 10 11 100 101 110 111 1000\n");
8
  • 1
    one might argue that using copy is cheating Dec 31, 2010 at 15:51
  • 13
    @Johannes actually I'm pretty sure printf has a loop :p
    – icecrime
    Dec 31, 2010 at 16:18
  • 1
    @litb: Note I didn't say that "using copy is cheating" Dec 31, 2010 at 17:31
  • 2
    @John : copying is cheating. do you doubt it? :P Jan 2, 2011 at 18:17
  • 1
    on a scale from 1 to 10, whats the chance I'm using binary?
    – Jordan
    Nov 28, 2012 at 9:06
270
votes

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

8
  • 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, 2010 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... Jan 2, 2011 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 3, 2011 at 2:40
  • 12
    @Joseph this is defined by 12.6/3 (C++03). Initialization is done in subscription order. Jan 3, 2011 at 9:56
  • 2
    @Joseph: And they're destructed in reverse order too, so you could use a destructor just as easily :) Jan 3, 2011 at 10:00
263
votes

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

8
  • 223
    I hope you wrote a program to generate that line. Dec 31, 2010 at 18:15
  • 32
    open("1000.c",'w').write('printf("%s");' % ("\n".join([str(x) for x in xrange(1,1000)]))) Jan 3, 2011 at 5:11
  • 53
    I hope that the program you wrote to generate that line didn't contain loop! Jan 3, 2011 at 6:19
  • 20
    A Vim macro would do the job quickly. Jan 4, 2011 at 19:00
  • 2
    A bit of Perl generates it in a fancy way: $r='printf("'; for (1..1000) { $r.="$_\\n" } $r.='");'; print $r;
    – sidyll
    Apr 27, 2011 at 18:29
212
votes
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! :)

4
  • 77
    my favorite after 'printf("numbers from 1 to 1000")' - silly questions require silly answers.
    – SEngstrom
    Jan 1, 2011 at 6:57
  • this is awesome. +1 for taking advantage of the ambiguity in the question. haha Jan 2, 2011 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, 2011 at 0: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, 2012 at 4:16
172
votes

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!

4
  • 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 3, 2011 at 1:47
  • 10
    @zakk: That's not strictly necessary - by default stdout is line buffered, so the \n will be enough to flush the output.
    – psmears
    Jan 4, 2011 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, 2011 at 3:50
  • danger of stackoverflow (for example in an embedded enviroment) Feb 3, 2011 at 18:31
166
votes

Using system commands:

system("/usr/bin/seq 1000");
4
  • 15
    High chance /usr/bin/seq uses a loop internally. :)
    – user142019
    Jun 6, 2011 at 14:09
  • @jokester: you mean, because Solaris/BSD doesn't have a seq utility (in the default setup)? <grin/>
    – sehe
    Oct 26, 2011 at 0: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... Nov 26, 2012 at 14:34
  • 1
    Some bright dude decided to change my answer, so that's not my mistake.
    – moinudin
    Nov 26, 2012 at 20:04
100
votes

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);
}
20
  • 29
    @Prasoon: It's a relation. Dec 31, 2010 at 8:03
  • 28
    requirement is "no conditionals" (if, switch, etc). not "no conditions" Dec 31, 2010 at 8:45
  • 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, 2010 at 9:38
  • 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. Jan 2, 2011 at 20:53
  • 4
    1 - i / 1000. No comparisons!
    – Thai
    Jan 4, 2011 at 16:28
96
votes

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

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);
}
6
  • It does not stop at 1000, though. It just keeps going. Jan 7, 2011 at 8: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, 2011 at 10:43
  • @eq Again, this compiles and runs just fine… Jan 15, 2011 at 18:49
  • 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
    – user332325
    Feb 3, 2011 at 9: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 6, 2012 at 5:36
71
votes

Easy as pie! :P

#include <iostream>

static int current = 1;

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

int main()
{
    print numbers [1000];
}
2
  • you might want to do "static int current = 0" otherwise will print from 2 to 1001.
    – Shinnok
    Mar 15, 2011 at 11:05
  • i changed ++current to current++
    – Zelix
    Mar 17, 2011 at 19:04
65
votes
#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);
}
1
  • 3
    Ummmm. Macros. It's whats for dinner.
    – EvilTeach
    Mar 14, 2011 at 19:26
42
votes

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.

3
  • 1
    Implicit loop in the library? But +1 anyway for a new approach.
    – Chris Lutz
    Jan 3, 2011 at 6:18
  • 11
    @Chris Don't most solutions have a hidden loop somewhere?
    – moinudin
    Jan 3, 2011 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 3, 2011 at 10:30
40
votes

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.

2
  • 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 3, 2012 at 8: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, 2013 at 20:38
34
votes

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, " "));
}
5
  • 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 :) Dec 31, 2010 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. Dec 31, 2010 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. Dec 31, 2010 at 23:05
  • implementation specific is undefined Dec 28, 2011 at 7: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. Dec 28, 2011 at 8:06
33
votes

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();
}
1
  • 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, 2011 at 1:02
32
votes
#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); }
0
30
votes

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);
}
2
  • 3
    all things alright, but why "void main()"? bad habits seldom go? :P Jan 2, 2011 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 2, 2011 at 22:56
29
votes

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

0
25
votes

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);
3
  • 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); Dec 31, 2010 at 8: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, 2010 at 9: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. Dec 31, 2010 at 18:39
24
votes

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;        
}
3
  • 3
    Your answer uses conditional statements, which are forbidden according to the question.
    – stevelove
    Jan 8, 2011 at 5:36
  • 4
    conditional statements are if else etc. I just used a logical operation!! Hpe it is clear!
    – Rajeev
    Jan 8, 2011 at 6: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, 2011 at 18:54
23
votes

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;
}
6
  • Calling main results in undefined behavior as I remember. Dec 31, 2010 at 10:14
  • 4
    It's perfectly legal C. @ybungalobill: You must be thinking of C++, where calling main() is specifically disallowed. Dec 31, 2010 at 10:44
  • @Michael: Maybe, I'm not very familiar with C. Dec 31, 2010 at 10:47
  • I think using Boost implies C++. Regardless, kudos for the Boost.PP solution.
    – me22
    Dec 31, 2010 at 21:11
  • 6
    The logical operators && and || would likely fall under "conditionals" since they short-circuit (as would ?:).
    – munificent
    Jan 1, 2011 at 23:18
22
votes

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

0
18
votes
#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];
}
0
15
votes
#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;
}
15
votes

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.

3
  • 2
    Can you call A2() without an argument like that?
    – Chris Lutz
    Jan 3, 2011 at 10:30
  • I was curious about that myself. It works properly with GCC, but I don't know if it's well-defined behavior.
    – keithmo
    Jan 4, 2011 at 3:33
  • Well-defined in C99, don't remember what C89 said, does cause trouble with at least some versions of MSVC if memory serves.
    – zwol
    Jan 26, 2011 at 1:03
15
votes

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;
}
0
13
votes

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();
}
2
  • 2
    You should avoid compiler optimisations then, to keep the otherwise unused j.
    – bandi
    Jan 3, 2011 at 12:08
  • 2
    He only need to add volatile to the declaration of j Jan 24, 2011 at 13:15

Not the answer you're looking for? Browse other questions tagged or ask your own question.