Drucken von 1 bis 1000 ohne Schleife oder Bedingungen

323

Aufgabe : Drucken Sie Zahlen von 1 bis 1000, ohne eine Schleife oder bedingte Anweisungen zu verwenden. Schreiben Sie die Anweisung printf()oder nicht einfach cout1000 Mal.

Wie würden Sie das mit C oder C ++ machen?

unbekannt
quelle
137
Die offensichtliche Antwort ist, 500 Anrufe zu verwenden printfund jedes Mal zwei Nummern zu drucken, nein?
James McNellis
433
printf ("Zahlen von 1 bis 1000");
Jondavidjohn
7
:?ist keine bedingte Aussage (es ist ein Ausdruck) ...
Chris Lutz
127
Das Interview Ihre Chance zu glänzen. Sagen Sie ihnen "Ohne Schleifen oder Bedingungen? Ein Kinderspiel. Ich kann es ohne Computer tun!" Ziehen Sie dann Stift und Notizblock heraus. Sie sehen Sie vielleicht verwirrt an, erklären aber nur, dass Sie wirklich nichts annehmen können, wenn Sie sich nicht auf eingebaute Sprachkonstrukte verlassen können.
JohnFx
8
Persönlich denke ich, dass es mehrere Antworten gab, die clevere, interessante Lösungen hatten. Ich denke auch, dass dies leicht eine schreckliche Interviewfrage sein könnte, aber es könnte einen guten Wert haben, solange der Interviewer wirklich nicht so sehr nach einer vollständig wohlgeformten Lösung sucht, als vielmehr danach, ob der Interviewte Ansätze in Betracht gezogen hat, die darauf hindeuten Kenntnisse über TMP oder die Verwendung von Konstrukten auf ungewöhnliche Weise. Ich denke, es wäre schlecht, wenn dies als reine "richtig / falsch" -Frage verwendet würde, aber wenn es als Ausgangspunkt einer Diskussion verwendet würde, könnte ich viel Wert sehen.
Michael Burr

Antworten:

785

Zeitrekursion kompilieren! : 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
quelle
8
Kann mir jemand erklären, wie das funktioniert? ziemlich beeindruckend.
Gath
28
@Zack: Lassen Sie uns real werden, wir drucken 1.000 Zeilen aus einem Programm, das geschrieben wurde, um Schleifen absichtlich zu vermeiden. Leistung ist kein Problem.
Dreamlax
42
Für diejenigen, die neugierig genug sind, dies zu kompilieren: Setzen Sie in g ++ -ftemplate-depth-1000. Das Standard-Rekursionsmaximum für Vorlagen beträgt 500.
Tom
6
Dies verwendet immer noch Bedingungen: Mustervergleich ist ein verherrlichtes if.
David K.
10
@dreamlax: Es ist nur eines der Dinge, die ich im Laufe der Jahre aus Erfahrung gelernt habe: Verwenden, es '\n'sei denn, Sie möchten wirklich spülen, verwenden, es ++isei denn, Sie benötigen tatsächlich den früheren Wert von i, als constReferenz übergeben, es sei denn, Sie haben einen guten Grund, nicht ... Wenn Entwickler aufhören, darüber nachzudenken (oder gar nicht erst anfangen), werden sie früher oder später auf ein Problem stoßen, bei dem es darauf ankommt, nur dass sie nicht einmal wussten, dass es Stellen gibt, an denen es wichtig sein könnte.
sbi
1195

Dieser kompiliert tatsächlich zu einer Assembly, die keine Bedingungen hat:

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

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


Bearbeiten: '&' hinzugefügt, damit die Adresse berücksichtigt wird und die Zeigerfehler vermieden werden.

Diese Version des oben genannten in Standard C, da sie nicht auf der Arithmetik von Funktionszeigern beruht:

#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);
}
Rechnung
quelle
17
Nun, der Code in dieser Antwort ist offensichtlich weder C noch C ++, also ist dies nur in Ordnung, wenn wir die Anforderung streichen. Dann kann sich jede Antwort qualifizieren, da ein hypothetischer Compiler möglicherweise nur das erforderliche Programm aus einer beliebigen Eingabe erstellt.
Gleichung
321
@PP, das ist ziemlich langwierig zu erklären, aber im Grunde jliegt es zunächst 1daran, dass es tatsächlich argcso ist, 1wenn das Programm ohne Argumente aufgerufen wird. Dann j/1000ist 0bis jwird 1000, danach ist es 1. (exit - main)ist natürlich der Unterschied zwischen den Adressen von exit()und main(). Das heißt (main + (exit - main)*(j/1000))ist main()bis jwird 1000, danach wird es exit(). Das Endergebnis ist, dass main()es aufgerufen wird, wenn das Programm gestartet wird, sich dann beim Inkrementieren 999 Mal rekursiv jaufruft und dann aufruft exit(). Puh :)
Frédéric Hamidi
7
Dies ist einer der erstaunlichsten Missbräuche von CI, die jemals gesehen wurden. Aber wird es auf allen Plattformen funktionieren?
Qwertie
13
@Mark: Dies ist keine Standardsignatur von main. Sie dürfen main nicht rekursiv aufrufen, und das Ergebnis des Subtrahierens von Funktionszeigern ist undefiniert.
Yakov Galka
9
Ja, ja, es ist aus den Gründen, die @ybungalobill angibt, kein streng legaler C ++ - Code, aber ich muss +1 für reinen Wahnsinn und die Tatsache, dass er auf einigen Plattformen kompiliert und funktioniert. Es gibt Zeiten, in denen die richtige Antwort auf "Aber es ist nicht Standard!" ist "Wen interessiert das?" :)
j_random_hacker
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; }

Ich bin überrascht, dass niemand dies gepostet zu haben scheint - ich dachte, es wäre der offensichtlichste Weg. 1000 = 5*5*5*8.

Darius Bacon
quelle
Leute haben dies gepostet. Die anderen Versionen übergeben die zu druckende Nummer, anstatt eine globale zu verwenden, aber es ist im Wesentlichen dieselbe Lösung.
Chris Lutz
1
@Chris, sie verwenden dieselbe Logik, die in Makros oder Vorlagen ausgedrückt wird, und sprengen die Codegröße, oder? Sie können auch die Ausgabezeichenfolge selbst anstelle von tausend printfs generieren.
Darius Bacon
Oh ja, ich sehe, dass Keiths Antwort die ganze Saite erzeugt, cool. :) Das habe ich vermisst.
Darius Bacon
43
Nun, nette Anstrengung, aber ziemlich seltsam, dass Sie 8 nicht in 2 * 2 * 2 zerlegt haben und daher die einzigartige Primfaktorisierung verwenden
David Heffernan
298

Sieht so aus, als müssten keine Schleifen verwendet werden

printf("1 10 11 100 101 110 111 1000\n");
Johannes Schaub - litb
quelle
1
Man könnte argumentieren, dass Verwenden copyBetrug ist
John Dibling
13
@ Johannes tatsächlich bin ich mir ziemlich sicher, dass printfes eine Schleife gibt: p
Eiskriminalität
1
@litb: Hinweis Ich habe nicht gesagt, dass "Verwenden copy ist Betrug"
John Dibling
2
@ John: Kopieren ist Betrug. zweifelst du daran : P
Nawaz
1
Wie groß ist die Chance, dass ich auf einer Skala von 1 bis 10 Binärdateien verwende?
Jordanien
270

Hier sind drei Lösungen, die ich kenne. Der zweite könnte jedoch argumentiert werden.

// 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
}

[ Bearbeiten: (1) und (4) können nur zum Kompilieren von Zeitkonstanten verwendet werden, (2) und (3) können auch für Laufzeitausdrücke verwendet werden - Bearbeiten beenden. ]]

ybungalobill
quelle
5
Außerdem würde ich darüber streiten, dass ein Kurzschluss keine Bedingung ist ... Keine Aussage, wahr, aber ein bedingter Ausdruck, würde ich sagen. Vorausgesetzt, wir definieren einen bedingten Ausdruck als "etwas, das bedingte Sprünge im Assembler ergibt".
Kos
5
Frage, die mich beim Lesen des Konstruktors 1 traf: Erfordert der Standard, dass jedes Element im Array nacheinander erstellt wird? Es wäre wichtig, wenn der Konstruktor Nebenwirkungen hätte. Ich bin sicher, dass jeder vernünftige Compiler es als 0-> 1000-Schleife implementiert, aber ich frage mich, ob Sie immer noch konform sein und rückwärts schleifen können ...
Joseph Garvin
6
@Joseph - Der Konstruktor sollte nicht davon betroffen sein, in welcher Reihenfolge die einzelnen Objekte initiiert werden, aber es ist eine gute Frage.
Chris Lutz
12
@ Joseph dies wird durch 12.6 / 3 (C ++ 03) definiert. Die Initialisierung erfolgt in Abonnementreihenfolge.
Johannes Schaub - litb
2
@ Joseph: Und sie sind auch in umgekehrter Reihenfolge zerstört, so dass Sie einen Destruktor genauso einfach verwenden können :)
j_random_hacker
263

Ich schreibe die printf-Anweisung nicht 1000 Mal!

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

Bitte ;)

Martin Thurau
quelle
223
Ich hoffe, Sie haben ein Programm geschrieben, um diese Zeile zu generieren.
Martin York
32
open ("1000.c", 'w'). write ('printf ("% s");'% ("\ n" .join ([str (x) für x in xrange (1.1000)]) ))
Tyler Eaves
53
Ich hoffe, dass das Programm, das Sie geschrieben haben, um diese Zeile zu generieren, keine Schleife enthielt!
Jeeyoung Kim
20
Ein Vim-Makro würde die Arbeit schnell erledigen.
StackedCrooked
2
Ein bisschen Perl erzeugt es auf ausgefallene Weise:$r='printf("'; for (1..1000) { $r.="$_\\n" } $r.='");'; print $r;
Sidyll
213
printf("%d\n", 2);
printf("%d\n", 3);

Es werden nicht alle Zahlen gedruckt , aber "Zahlen von 1 bis 1000 drucken ". Mehrdeutige Frage zum Sieg! :) :)

Matthew Flaschen
quelle
77
Mein Favorit nach 'printf ("Zahlen von 1 bis 1000")' - dumme Fragen erfordern dumme Antworten.
SEngstrom
das ist fantastisch. +1, um die Mehrdeutigkeit in der Frage auszunutzen. haha
Nawaz
2
Bearbeitet; In keiner Weise, Form oder Form hat dieser Code print "Print numbers from 1 to 1000."- mehrdeutige Frage für den Sieg, ungenaue Beschreibungen saugen :)
sehe
Wow, in letzter Zeit gab es ein bisschen Vandalismus bei den Antworten auf diese Frage. Etwas sagt mir, dass wir diese Sperre auf eine historische Sperre aktualisieren sollten.
BoltClock
172

Lösen Sie einen schwerwiegenden Fehler aus! Hier ist die Datei 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);
}

Kompilieren und dann an einer Shell-Eingabeaufforderung ausführen:

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

Dies druckt tatsächlich die Zahlen von 1 bis 1000 ohne Schleifen oder Bedingungen!

Aaron Maxwell
quelle
43
Sie sollten fflush (stdout) aufrufen. nach jedem printf () ... Wenn ein Programm abstürzt, kann nicht garantiert werden, dass der Ausgabepuffer auf dem Bildschirm gedruckt wird.
Zakk
10
@zakk: Das ist nicht unbedingt erforderlich - standardmäßig ist stdout zeilengepuffert, sodass \ndies ausreicht, um die Ausgabe zu leeren.
psmears
24
stdout ist zeilengepuffert, wenn festgestellt werden kann, dass es sich um ein interaktives Gerät handelt , andernfalls ist es vollständig gepuffert. Wenn der Professor stdout zur automatischen Überprüfung in eine Datei umleitet,
schlagen
Gefahr eines Stapelüberlaufs (zum Beispiel in einer eingebetteten Umgebung)
Hernán Eche
166

Verwenden von Systembefehlen:

system("/usr/bin/seq 1000");
Marcog
quelle
15
High Chance /usr/bin/seqverwendet intern eine Schleife. :)
@jokester: Sie meinen, weil Solaris / BSD kein seqDienstprogramm hat (im Standard-Setup)? <
grin
Ich hasse es, das zu sagen (nun, nein, ich nicht), aber es gibt einen Fehler in Ihrer Lösung. Es werden nicht die richtigen Zahlen ausgedruckt. :) Hier ist die Lösung: system("/bin/echo {1..1000}"); Wenn Sie nur den Unit-Test zuerst geschrieben hätten ...
Don Branson
1
Ein kluger Kerl hat beschlossen, meine Antwort zu ändern, also ist das nicht mein Fehler.
Moinudin
100

Ungetestet, sollte aber Vanille Standard C sein:

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);
}
großartig
quelle
29
@Prasoon: Es ist eine Beziehung.
Yakov Galka
28
Voraussetzung ist "keine Bedingungen" (if, switch, etc). nicht "keine Bedingungen"
jon_darkstar
32
<ist keine Bedingung. Es ist ein relationaler Operator. if/ elseist eine bedingte Aussage. ?:ist ein bedingter Operator. <ist nur ein Operator, der einen booleschen Wert zurückgibt. Es ist wahrscheinlich eine einzelne Maschinenanweisung ohne Sprünge oder irgendetwas.
Chris Lutz
12
@ Chris Lutz: Auf x86, dann ist es 3 Anweisungen: cmpl, setle, und movzbl. x86-64 ist das plus a cltq. PowerPC besteht aus 2 Anweisungen: cmpwiund crnot.
Adam Rosenfield
4
1 - i / 1000. Keine Vergleiche!
Thai
96

Ein bisschen langweilig im Vergleich zu anderen hier, aber wahrscheinlich das, wonach sie suchen.

#include <stdio.h>

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

void main(void) {
    f(1000);
}
Aaron
quelle
Hat es kürzer gemacht. setze i = 1 außerhalb von main und dann innerhalb von main: printf ("% d \ n", 11 - i) && --i && main (i);
Jftuga
3
@Jens Schauder: Indem Sie die faule &&Bewertung in der ersten Zeile von nutzen f().
Rafał Dowgird
10
Das ist nicht langweilig, es ist einfach. Wenn Sie mit einer kurzen Funktion dasselbe tun können wie mit einem großen Durcheinander an Vorlagenmagie, dann sollten Sie dies mit der Funktion tun :)
amertune
21
Das && ist eine Bedingung. Ein mathematisches UND bewertet beide Seiten (wie das Java & und das Ada "UND"). && wertet den 2. Operator nur aus, wenn (hier ist es) der erste wahr ist. Oder ein anderes Beispiel: In Ada heißt der Kurzschlussoperator "ODER DANN" - wobei DANN verwendet wird, um den bedingten Aspekt anzuzeigen. Entschuldigung, Sie hätten das genauso gut nutzen können? : Operator.
Martin
Keine Notwendigkeit, sich zu entschuldigen. && ist ein Vergleichsoperator. Der ternäre Operator ist eine Bedingung.
Aaron
71

Die Aufgabe hat nie angegeben, dass das Programm nach 1000 beendet werden muss.

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

int main(){
   f(1);
}

( Kann verkürzt werden, wenn Sie ./a.out ohne zusätzliche Parameter ausführen. )

void main(int n) {
   printf("%d\n", n);
   main(n+1);
}
Brian
quelle
Es hört jedoch nicht bei 1000 auf. Es geht einfach weiter.
Remy Lebeau
Kann nur gekürzt werden, wenn Sie die Anforderungen von C oder C ++ streichen. Dann reicht jedes "Programm" aus, da ein theoretischer Compiler das gewünschte Programm (aus jeder Eingabe) generieren könnte.
Gleichung
@eq Wieder kompiliert und läuft dies gut ...
Mark McDonald
72
Nachträglich: Wir können uns sogar der scheinbaren Mathematik entziehen . Wenn wir beschäftigen rand(), werden wir alle Zahlen von 1 bis 1000 drucken. Schließlich =: P
5
@pooh: Nicht unbedingt, da rand () die Chance hat, sich nach einer bestimmten Sequenz zu wiederholen, und diese Sequenz möglicherweise nicht in die für dieses Problem
festgelegte
71

Einfach wie Torte! : P.

#include <iostream>

static int current = 1;

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

int main()
{
    print numbers [1000];
}
Zelix
quelle
Vielleicht möchten Sie "static int current = 0"
ausführen,
Ich habe ++ aktuell in aktuell ++ geändert
Zelix
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
quelle
3
Ummmm. Makros. Es ist was zum Abendessen.
EvilTeach
42

Wir können 1000 Threads starten, von denen jeder eine der Zahlen druckt. Installieren Sie OpenMPI , kompilieren Sie mit mpicxx -o 1000 1000.cppund führen Sie es mit aus mpirun -np 1000 ./1000. Sie müssen wahrscheinlich Ihr Deskriptorlimit mit limitoder erhöhen ulimit. Beachten Sie, dass dies ziemlich langsam ist, es sei denn, Sie haben viele Kerne!

#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();
}

Natürlich werden die Nummern nicht unbedingt in der richtigen Reihenfolge gedruckt, aber die Frage erfordert nicht, dass sie bestellt werden.

Moinudin
quelle
1
Implizite Schleife in der Bibliothek? Aber +1 trotzdem für einen neuen Ansatz.
Chris Lutz
11
@Chris Haben die meisten Lösungen nicht irgendwo eine versteckte Schleife?
Moinudin
Ich nehme an, wenn Sie den Ansatz "Schleifen im Compiler" wählen. Da MPI::Init()ich mir (außerhalb einer möglichen Schleife über die Argumente in ) keine Schleifen in der tatsächlichen Binärdatei Ihres 1000.cpp-Programms vorstellen kann, habe ich Ihnen eine +1 gegeben, obwohl bei der Ausführung sicherlich Schleifen ausgeführt werden.
Chris Lutz
40

Mit einfachem 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;
}

Natürlich können Sie dieselbe Idee auch für andere Basen implementieren (2: print2 print4 print8 ...), aber die hier vorgeschlagene Nummer 1000 basiert auf Basis 10. Sie können auch die Anzahl der Zeilen, die Zwischenfunktionen hinzufügen, ein wenig reduzieren: print2() print10() print20() print100() print200() print1000()und andere äquivalente Alternativen.

leonbloy
quelle
Warum schlägt die Zahl 1000 Basis 10 vor? In jeder Positionsnotation mit Basis Bist 1000 eine vollkommen gültige Zahl und immer gleich B^3.
Philip
Ich habe nur gemeint, dass sich angesichts der Darstellung der Zahl in Basis 10 die Faktorisierung "10x10x10" anbietet, aber dass andere Alternativen möglich sind. Ich denke, ich hätte "Faktorisierung" anstelle von "Basis"
sagen sollen
34

Verwenden Sie einfach std :: copy () mit einem speziellen 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, " "));
}
Loki Astari
quelle
Ich denke, Ihr Code beginnt bei 0. Stimmen Sie auch Chris zu, die Frage, wie ich sie vor Jahren gesehen habe, wurde als "ohne Bibliotheken außer E / A" angegeben. noch +1 :)
Yakov Galka
3
@ Chris Lutz: Die Implementierung der Kopie ist undefiniert. Ich kann sogar Vorlagencode wie oben verwenden (Sie wissen es einfach nicht). Man kann also nicht sagen, dass es eine Schleife verwendet, weil wir es nicht wissen.
Martin York
7
Eigentlich wäre meine Nit-Auswahl nicht die implizite Schleife, sondern std::copydie implizite Bedingung in der operator !=(). Unabhängig davon ist es eine clevere Art, einen Bereich zu verarbeiten, und ich suche nach cleveren Ansätzen, um auf Fragen wie diese zu antworten.
Michael Burr
Implementierungsspezifisch ist undefiniert
selvaiyyamperumal
@selvaiyyamperumal: Ich weiß nicht genau, wovon du sprichst. Aber wenn Sie über Verhalten sprechen, stimmt der Standard nicht mit Ihnen überein. "Implementierungsdefiniertes Verhalten" bedeutet, dass es gut definiert ist, aber von der Implementierung explizit dokumentiert werden muss. "Undefiniertes Verhalten" bedeutet, dass alles passieren kann.
Martin York
33

Funktionszeiger (ab) verwenden. Keine Präprozessor-Magie zur Steigerung der Ausgabe. 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.
quelle
3
Daran habe ich gedacht. Eine frühere Person sagte, dass 5 * 5 * 5 * 8 = 1000. Ich fand es lustig, dass ihm die offensichtlichen 10 ^ 3 fehlten. Schöne Lösung!
Evan Moran
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
quelle
30

Hässliche C-Antwort (nur für einen Stapelrahmen pro Zehnerpotenz abgewickelt):

#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
quelle
3
alles in Ordnung, aber warum "void main ()"? schlechte Gewohnheiten gehen selten? : P
Nawaz
30
@Nawaz: Da dies heimlich eine Windows-GUI-App ist, spielt es keine Rolle. Ich habe es nur "main" genannt, weil ich an Hummer gedacht habe und eine schreckliche Rechtschreibung habe.
Martin
29

Paketüberfluss:

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

Dies ist für einen 8-MB-Stapel. Jeder Funktionsaufruf scheint ungefähr 32 Bytes zu dauern (daher die 32 * 1000). Aber als ich es dann ausführte, kam ich nur auf 804 (daher die 196 * 32; vielleicht hat die C-Laufzeit andere Teile im Stapel, die Sie ebenfalls abziehen müssen).

user560766
quelle
25

Spaß mit Funktionszeigern (keiner der neuen TMPs benötigt):

#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;
}

Als Randnotiz: Ich habe das Verbot von Bedingungen auf logische und relationale Operatoren ausgedehnt. Wenn Sie eine logische Negation zulassen, kann der rekursive Aufruf wie folgt vereinfacht werden:

funcs[!!(limit-1)](x+1, limit-1);
Michael Burr
quelle
Ich mag die Art und Weise, wie du es mit der Bitverschiebung hast. Aber was macht der Doppelknall mit Ihrer nachträglichen Vereinfachung? es ist bitweise oder logisch? Ich funcs[!!(limit-1)](x+1, limit-1);
bin
Ich hätte lieber eine Single !und wechsle die Funktionszeiger-Array-Elemente, aber ich weiß nicht, ob das gut mit deiner anderen Verrücktheit zusammenpasst.
Chris Lutz
@Chris: Ich stimme vollkommen zu - aber ich habe erst nach dem Posten überlegt, logische / Beziehungsoperatoren zu verwenden, und ich dachte, ein einzeiliger Patch wäre angemessener. Außerdem passt es ein wenig besser zu dem ganzen verschleierten Gefühl des Problems.
Michael Burr
24

Ich denke, diese Antwort wird sehr einfach und leicht zu verstehen sein.

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;        
}
Pappu
quelle
3
Ihre Antwort verwendet bedingte Anweisungen, die gemäß der Frage verboten sind.
stevelove
4
Bedingte Anweisungen sind, wenn sonst usw. Ich habe gerade eine logische Operation verwendet !! Hpe es ist klar!
Pappu
2
Sogar in Ihren Kommentaren haben Sie geschrieben: "Wenn ja, rufen Sie die rekursive Funktion zum Drucken auf". Eine Bedingung, die nicht offensichtlich geschrieben wurde, ist immer noch eine Bedingung. Der num-Standardwert ist ebenfalls eine Bedingung.
Gerry
23

Ich habe den ganzen Spaß verpasst, all die guten C ++ - Antworten wurden bereits veröffentlicht!

Dies ist das Seltsamste, was ich mir einfallen lassen könnte. Ich würde jedoch nicht wetten, dass es legal ist, C99: p

#include <stdio.h>

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

Ein anderer mit ein wenig Betrug:

#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, ~));
}

Letzte Idee, gleicher 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;
}
Eiskriminalität
quelle
Das Aufrufen mainführt zu undefiniertem Verhalten, wie ich mich erinnere.
Yakov Galka
4
Es ist vollkommen legal. C. @ybungalobill: Sie müssen an C ++ denken, wo das Aufrufen von main () ausdrücklich verboten ist.
Michael Foukarakis
@ Michael: Vielleicht bin ich nicht sehr vertraut mit C.
Yakov Galka
Ich denke, die Verwendung von Boost impliziert C ++. Unabhängig davon ein großes Lob für die Boost.PP-Lösung.
Me22
6
Die logischen Operatoren &&und ||würden wahrscheinlich unter "Bedingungen" fallen, da sie (wie ?:) kurzschließen .
Munificent
22

Einfach wie Torte:

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

Ausführungsmethode:

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"

Die Spezifikation besagt nicht, dass die Sequenz innerhalb des Codes generiert werden muss :)

Rodrigo
quelle
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
quelle
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
quelle
15

Mehr Präprozessor-Missbrauch:

#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;
}

Ich fühle mich so schmutzig; Ich denke, ich gehe jetzt duschen.

Keithmo
quelle
2
Können Sie A2()ohne ein solches Argument anrufen ?
Chris Lutz
Darauf war ich selbst neugierig. Es funktioniert richtig mit GCC, aber ich weiß nicht, ob es ein genau definiertes Verhalten ist.
Keithmo
In C99 gut definiert, erinnere mich nicht, was C89 gesagt hat, verursacht Probleme mit zumindest einigen Versionen von MSVC, wenn Speicher zur Verfügung steht.
zwol
15

Wenn POSIX-Lösungen akzeptiert werden:

#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
quelle
13

Da es keine Einschränkung für Bugs gibt ..

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

Oder noch besser (?),

#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
quelle
2
Sie sollten dann Compiler-Optimierungen vermeiden, um das ansonsten nicht verwendete j beizubehalten.
Bandi
2
Er muss nur volatiledie Erklärung vonj
Patrick Schlüter