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?


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

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

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.


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

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


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


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


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!


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

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

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

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

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

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

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.


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.


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

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

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

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

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


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

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

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

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


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

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

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.


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

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

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.