Mencetak 1 hingga 1000 tanpa loop atau kondisional


323

Tugas : Mencetak angka dari 1 hingga 1000 tanpa menggunakan perulangan atau pernyataan kondisional. Jangan hanya menulis printf()atau coutpernyataan 1000 kali.

Bagaimana Anda melakukannya dengan menggunakan C atau C ++?


137
Jawaban yang jelas adalah menggunakan 500 panggilan ke printfdan mencetak dua nomor setiap kali, bukan?
James McNellis

433
printf ("angka dari 1 hingga 1000");
jondavidjohn

7
:?bukan pernyataan kondisional (ini ungkapan) ...
Chris Lutz

127
Wawancarai kesempatan Anda untuk bersinar. Beri tahu mereka "Tanpa loop atau kondisional? Permainan anak-anak. Saya bisa melakukannya tanpa komputer!" Lalu tarik keluar pulpen dan notepad. Mereka mungkin memberi Anda pandangan bingung, tetapi cukup jelaskan bahwa jika Anda tidak dapat mengandalkan konstruksi bahasa yang dibangun, Anda benar-benar tidak dapat mengasumsikan apa pun.
JohnFx

8
Secara pribadi, saya pikir ada beberapa jawaban yang memiliki solusi cerdas dan menarik. Saya juga berpikir bahwa sementara ini bisa dengan mudah menjadi pertanyaan wawancara yang mengerikan, mungkin ada nilai yang baik di dalamnya, selama pewawancara benar-benar tidak mencari solusi yang benar-benar baik seperti mencari apakah orang yang diwawancarai mempertimbangkan pendekatan yang mengindikasikan pengetahuan tentang TMP atau menggunakan konstruksi dengan cara yang tidak biasa. Saya pikir akan buruk jika ini digunakan sebagai pertanyaan murni 'benar-benar / salah', tetapi jika digunakan sebagai titik awal diskusi, saya bisa melihat banyak nilai.
Michael Burr

Jawaban:


785

Kompilasi rekursi waktu! : 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
Adakah yang bisa menjelaskan kepada saya bagaimana cara kerjanya? cukup mengesankan.
Gat

28
@Zack: Ayo menjadi nyata, kami mencetak 1.000 baris dari program yang ditulis untuk menghindari loop. Performa bukan masalah.
dreamlax

42
Bagi mereka yang cukup penasaran untuk mengkompilasi ini: di g ++, set -ftemplate-depth-1000. Maksimum rekursi templat default adalah 500.
Tom

6
Ini masih menggunakan kondisi: pencocokan pola dimuliakan jika.
David K.

10
@dreamlax: Ini hanya salah satu dari hal-hal yang telah saya pelajari dari pengalaman selama bertahun-tahun: gunakan '\n'kecuali jika Anda benar-benar ingin memerah, gunakan ++ikecuali Anda benar-benar membutuhkan nilai sebelumnya i, lewati constreferensi kecuali Anda memiliki alasan kuat untuk tidak ... Ketika pengembang berhenti memikirkan hal ini (atau bahkan tidak pernah memulai), mereka akan, cepat atau lambat, mengalami masalah di mana ini penting, hanya saja mereka bahkan tidak tahu ada titik di mana itu mungkin penting.
sbi

1195

Yang ini sebenarnya mengkompilasi ke perakitan yang tidak memiliki persyaratan:

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

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


Sunting: Ditambahkan '&' sehingga akan mempertimbangkan alamat maka menghindari kesalahan pointer.

Versi di atas dalam standar C, karena tidak bergantung pada aritmatika pada pointer fungsi:

#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
Nah, kode dalam jawaban ini jelas bukan C atau C ++, jadi ini tidak masalah hanya jika kita membatalkan persyaratan. Maka jawaban apa pun mungkin memenuhi syarat karena penyusun hipotesis mungkin hanya menghasilkan program yang diperlukan dari input apa pun.
Persamaan

321
@PP, itu cukup panjang untuk dijelaskan, tetapi pada dasarnya, pada jawalnya 1karena sebenarnya argc, yaitu 1jika program dipanggil tanpa argumen. Kemudian, j/1000adalah 0sampai jmenjadi 1000, setelah itu 1. (exit - main)tentu saja adalah perbedaan antara alamat exit()dan main(). Itu berarti (main + (exit - main)*(j/1000))adalah main()sampai jmenjadi 1000, setelah itu menjadi exit(). Hasil akhirnya adalah yang main()dipanggil saat program dijalankan, kemudian memanggil dirinya secara rekursif 999 kali sambil menambah j, kemudian memanggil exit(). Wah :)
Frédéric Hamidi

7
Ini adalah salah satu penyalahgunaan CI yang paling menakjubkan yang pernah ada. Tetapi apakah ini akan bekerja pada semua platform?
Qwertie

13
@ Mark: ini adalah tanda tangan non-standar utama, Anda dilarang memanggil utama secara rekursif, dan hasil pengurangan pointer fungsi tidak ditentukan.
Yakov Galka

9
Ya, ya, ini bukan kode C ++ legal untuk alasan yang diberikan @ybungalobill, tapi saya harus memberi +1 untuk kegilaan belaka dan fakta bahwa ia mengkompilasi dan bekerja pada beberapa platform. Ada kalanya respon yang benar untuk "Tapi itu bukan standar!" adalah "Siapa yang peduli!" :)
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; }

Saya terkejut tidak ada yang tampaknya telah memposting ini - saya pikir itu adalah cara yang paling jelas. 1000 = 5*5*5*8.


Orang telah memposting ini. Versi lain meneruskan nomor untuk dicetak daripada menggunakan global, tetapi pada dasarnya solusi yang sama.
Chris Lutz

1
@ Chris, mereka menggunakan logika yang sama diekspresikan dalam makro atau templat, meledakkan ukuran kode, kan? Anda mungkin juga menghasilkan string output itu sendiri daripada seribu printfs.
Darius Bacon

Oh ya, saya melihat jawaban Keith menghasilkan seluruh string, keren. :) Saya melewatkan itu.
Darius Bacon

43
Yah, usaha yang bagus, tetapi agak aneh bahwa Anda tidak menguraikan 8 menjadi 2 * 2 * 2 dan dengan demikian menggunakan factorisation prima yang unik
David Heffernan

298

Sepertinya tidak perlu menggunakan loop

printf("1 10 11 100 101 110 111 1000\n");

1
orang mungkin berpendapat bahwa menggunakan copyitu curang
John Dibling

13
@ Johnannes sebenarnya saya cukup yakin printfmemiliki loop: p
icecrime

1
@ litb: Catatan Saya tidak mengatakan bahwa "menggunakan copy adalah kecurangan"
John Dibling

2
@ John: menyalin itu curang. apakah anda meragukannya? : P
Nawaz

1
pada skala dari 1 hingga 10, bagaimana saya menggunakan biner?
Jordan

270

Inilah tiga solusi yang saya tahu. Yang kedua mungkin diperdebatkan.

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

[ Sunting: (1) dan (4) dapat digunakan hanya untuk konstanta waktu kompilasi, (2) dan (3) dapat digunakan untuk ekspresi runtime juga - sunting akhir. ]


5
Juga, saya akan berdebat tentang hubungan arus pendek yang tidak menjadi persyaratan ... Bukan pernyataan, benar, tetapi ekspresi kondisi, saya katakan. Asalkan kita mendefinisikan ekspresi kondisional sebagai "sesuatu yang menghasilkan lompatan kondisional dalam assembler".
Kos

5
Pertanyaan yang menghantam saya ketika membaca konstruktor satu: Apakah mandat standar bahwa setiap item dalam array dibangun secara berurutan? Akan menjadi masalah jika konstruktor memiliki efek samping. Saya yakin setiap kompiler waras mengimplementasikannya sebagai 0 -> 1000 loop tapi saya ingin tahu apakah Anda masih bisa compliant dan loop mundur ...
Joseph Garvin

6
@ Joseph - Konstruksi satu tidak boleh terpengaruh oleh apa urutan objek individu dimulai, tetapi itu adalah pertanyaan yang bagus.
Chris Lutz

12
@ Joseph ini didefinisikan oleh 12.6 / 3 (C ++ 03). Inisialisasi dilakukan dalam urutan berlangganan.
Johannes Schaub - litb

2
@ Joseph: Dan mereka hancur dalam urutan terbalik juga, sehingga Anda dapat menggunakan destruktor dengan mudah :)
j_random_hacker

263

Saya tidak menulis pernyataan printf 1000 kali!

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

Sama-sama ;)


223
Saya harap Anda menulis sebuah program untuk menghasilkan baris itu.
Martin York

32
buka ("1000.c", 'w'). write ('printf ("% s");'% ("\ n" .join ([str (x) untuk x dalam xrange (1,1000)]) ))
Tyler Eaves

53
Saya harap program yang Anda tulis untuk menghasilkan baris itu tidak mengandung loop!
Jeeyoung Kim

20
Makro Vim akan melakukan pekerjaan dengan cepat.
StackedCrooked

2
Sedikit Perl menghasilkannya dengan cara mewah:$r='printf("'; for (1..1000) { $r.="$_\\n" } $r.='");'; print $r;
sidyll

213
printf("%d\n", 2);
printf("%d\n", 3);

Itu tidak mencetak semua angka, tetapi "Cetak angka dari 1 hingga 1000." Pertanyaan mendua untuk menang! :)


77
favorit saya setelah 'printf ("angka 1 hingga 1000")' - pertanyaan konyol memerlukan jawaban konyol.
SEngstrom

ini luar biasa. +1 untuk memanfaatkan ambiguitas dalam pertanyaan. haha
Nawaz

2
Diedit; tidak dalam cara, bentuk, atau bentuk melakukan kode ini print "Print numbers from 1 to 1000."- pertanyaan ambigu untuk menang, deskripsi akurat mengisap :)
sehe

Wow, sudah ada sedikit vandalisme pada jawaban pertanyaan ini akhir-akhir ini. Sesuatu memberitahu saya bahwa kita harus memutakhirkan kunci itu menjadi kunci historis.
BoltClock

172

Trigger kesalahan fatal! Inilah file itu, 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);
}

Kompilasi, lalu jalankan pada prompt shell:

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

Ini memang mencetak angka dari 1 hingga 1000, tanpa loop atau persyaratan!


43
Anda harus memanggil fflush (stdout); setelah setiap printf () ... Ketika sebuah program crash, itu tidak dijamin bahwa buffer output akan dicetak di layar.
zakk

10
@ zakk: Itu tidak sepenuhnya diperlukan - secara default stdout adalah buffered baris, sehingga \nakan cukup untuk menyiram output.
psmears

24
stdout adalah buffer line jika dapat ditentukan sebagai perangkat interaktif , jika tidak buffered sepenuhnya. Jika profesor mengalihkan stdout ke file untuk pemeriksaan otomatis, Anda akan gagal :-)
paxdiablo

bahaya stackoverflow (misalnya dalam lingkungan tertanam)
Hernán Eche

166

Menggunakan perintah sistem:

system("/usr/bin/seq 1000");

15
Peluang tinggi /usr/bin/seqmenggunakan loop secara internal. :)

@jokester: maksud Anda, karena Solaris / BSD tidak memiliki sequtilitas (dalam pengaturan default)? <nyengir />
sehe

Saya benci mengatakan ini (well, tidak, saya tidak), tetapi ada bug dalam solusi Anda. Itu tidak mencetak set angka yang tepat. :) Inilah solusinya: system("/bin/echo {1..1000}"); Andai saja Anda telah menulis unit test terlebih dahulu ...
Don Branson

1
Beberapa pria cerdas memutuskan untuk mengubah jawaban saya, jadi itu bukan kesalahan saya.
moinudin

100

Belum diuji, tetapi harus vanilla standar 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);
}

29
@Prasoon: Ini sebuah hubungan.
Yakov Galka

28
persyaratan adalah "tanpa syarat" (jika, aktifkan, dll). bukan "tanpa syarat"
jon_darkstar

32
<bukan suatu kondisi. Ini operator relasional. ifSaya elseadalah pernyataan kondisional. ?:adalah operator bersyarat. <hanyalah operator yang mengembalikan nilai boolean. Ini mungkin instruksi mesin tunggal tanpa lompatan atau apa pun.
Chris Lutz

12
@ Chris Lutz: Pada x86, itu 3 instruksi: cmpl, setle, dan movzbl. x86-64 adalah bahwa plus a cltq. PowerPC adalah 2 instruksi: cmpwidan crnot.
Adam Rosenfield

4
1 - i / 1000. Tidak ada perbandingan!
Thai

96

Agak membosankan dibandingkan dengan yang lain di sini, tapi mungkin yang mereka cari.

#include <stdio.h>

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

void main(void) {
    f(1000);
}

Buat lebih pendek. set i = 1 di luar main dan kemudian di dalam main: printf ("% d \ n", 11 - i) && --i && main (i);
jftuga

3
@Jens Schauder: Dengan memanfaatkan &&evaluasi malas di baris pertama f().
Rafał Dowgird

10
Ini tidak membosankan, itu sederhana. Jika Anda dapat melakukan hal yang sama dengan fungsi pendek seperti yang Anda dapat dengan kekacauan besar template templat, maka Anda harus melakukannya dengan fungsi :)
amertune

21
&& adalah persyaratan. AND matematika akan mengevaluasi kedua belah pihak (seperti Java & dan Ada "DAN" tidak). && akan mengevaluasi operator ke-2 hanya jika (ini dia) yang pertama adalah benar. Atau contoh lain: Di Ada itu operator hubung singkat disebut "ATAU KEMUDIAN" - menggunakan KEMUDIAN untuk menunjukkan aspek bersyarat. Maaf, Anda bisa menggunakan saja? : operator.
Martin

Tidak perlu meminta maaf. && adalah operator pembanding. Operator ternary adalah suatu kondisi.
Aaron

71

Tugas tidak pernah menentukan bahwa program harus dihentikan setelah 1000.

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

int main(){
   f(1);
}

( Dapat disingkat menjadi ini jika Anda menjalankan ./a.out tanpa params tambahan )

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

Itu tidak berhenti pada 1000, meskipun. Itu terus berjalan.
Remy Lebeau

Dapat dipersingkat hanya jika Anda membatalkan persyaratan C atau C ++. Maka "program" apa pun akan dilakukan, karena kompilator teoretis dapat menghasilkan program yang Anda inginkan (dari input apa pun).
Persamaan

@ eq Sekali lagi, ini mengkompilasi dan berjalan dengan baik ...
Mark McDonald

72
Sebagai renungan: kita bahkan dapat menghindari matematika yang tampak jelas . Jika kami mempekerjakan rand(), kami akan mencetak semua angka dari 1 hingga 1000. Akhirnya =: P

5
@pooh: Tidak harus, karena rand () memiliki kesempatan untuk mengulangi setelah urutan tertentu, dan urutan yang mungkin tidak jatuh dalam solusi yang ditetapkan untuk masalah ini
dchhetri

71

Mudah seperti pai! : P

#include <iostream>

static int current = 1;

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

int main()
{
    print numbers [1000];
}

Anda mungkin ingin melakukan "static int current = 0" jika tidak akan mencetak dari 2 hingga 1001.
Shinnok

saya mengubah ++ saat ini menjadi ++ saat ini
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. Makro. Ini untuk makan malam.
EvilTeach

42

Kami dapat meluncurkan 1000 utas, masing-masing mencetak salah satu nomor. Instal OpenMPI , kompilasi menggunakan mpicxx -o 1000 1000.cppdan jalankan menggunakan mpirun -np 1000 ./1000. Anda mungkin perlu menambah batas deskriptor menggunakan limitatau ulimit. Perhatikan bahwa ini akan agak lambat, kecuali jika Anda memiliki banyak core!

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

Tentu saja, angkanya tidak harus dicetak secara berurutan, tetapi pertanyaannya tidak mengharuskan mereka dipesan.


1
Loop implisit di perpustakaan? Tapi +1 tetap untuk pendekatan baru.
Chris Lutz

11
@ Chris Tidak sebagian besar solusi memiliki loop tersembunyi di suatu tempat?
moinudin

Saya kira, jika Anda mengambil pendekatan "loop in the compiler". Karena (di luar kemungkinan loop atas argumen di MPI::Init()) Saya tidak bisa membayangkan loop dalam biner sebenarnya dari program 1000.cpp Anda, saya memberi Anda +1, meskipun pasti ada loop berjalan ketika Anda menjalankannya.
Chris Lutz

40

Dengan C polos:

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

Tentu saja, Anda dapat menerapkan ide yang sama untuk pangkalan lain (2: print2 print4 print8 ...) tetapi angka 1000 di sini menyarankan pangkalan 10. Anda juga dapat mengurangi sedikit garis yang menambahkan fungsi perantara: print2() print10() print20() print100() print200() print1000()dan alternatif lain yang setara.


Mengapa angka 1000 menyarankan basis 10? Dalam setiap notasi posisi dengan basis B, 1000 adalah angka yang benar-benar valid dan selalu sama B^3.
Philip

Saya hanya bermaksud bahwa, mengingat bagaimana angka tersebut diwakili dalam basis 10, faktorisasi "10x10x10" menyarankan dirinya sendiri, tetapi alternatif lain dimungkinkan. Saya kira saya seharusnya mengatakan "faktorisasi" bukannya "basis"
leonbloy

34

Cukup gunakan std :: copy () dengan iterator khusus.

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

Saya pikir kode Anda mulai dari 0. Juga setuju dengan Chris, pertanyaan seperti yang saya lihat tahun lalu dinyatakan sebagai "tanpa perpustakaan kecuali untuk IO". Belum +1 :)
Yakov Galka

3
@ Chris Lutz: Implementasi salinan tidak ditentukan. Saya bahkan dapat menggunakan kode templat seperti di atas (Anda tidak tahu;) Jadi Anda tidak bisa mengatakan itu menggunakan loop karena kami tidak tahu.
Martin York

7
Sebenarnya, nit pick saya tidak akan menjadi loop implisit dalam std::copysebanyak kondisi implisit dalam operator !=(). Bagaimanapun juga, ini adalah cara yang cerdas dalam memproses suatu rentang, dan pendekatan cerdas adalah apa yang saya cari dalam menanggapi pertanyaan-pertanyaan seperti ini.
Michael Burr

implementasi spesifik tidak ditentukan
selvaiyyamperumal

@selvaiyyamperumal: Tidak yakin persis apa yang Anda bicarakan. Tetapi jika Anda berbicara tentang perilaku maka standar tidak setuju dengan Anda. "Perilaku yang Didefinisikan Implementasi" berarti didefinisikan dengan baik tetapi harus didokumentasikan secara eksplisit oleh implementasi. "Perilaku Tidak Terdefinisi" berarti segala sesuatu dapat terjadi.
Martin York

33

Pointer fungsi (ab) gunakan. Tidak ada keajaiban preprosesor untuk meningkatkan 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();
}

3
Inilah yang saya pikirkan. Orang sebelumnya mengatakan bahwa 5 * 5 * 5 * 8 = 1000. Saya pikir itu lucu dia kehilangan 10 ^ 3 yang jelas. Solusi bagus!
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

Jawaban jelek Ugly (belum dibuka hanya untuk satu frame stack per daya 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);
}

3
semua hal baik-baik saja, tetapi mengapa "void main ()"? kebiasaan buruk jarang pergi? : P
Nawaz

30
@Nawaz: Karena ini diam-diam adalah aplikasi Windows GUI, jadi tidak masalah. Saya hanya menyebutnya "utama" karena saya berpikir tentang lobster dan memiliki ejaan yang mengerikan.
Martin

29

Stack overflow:

#include <stdio.h>

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

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

Ini untuk tumpukan 8MB. Setiap pemanggilan fungsi tampaknya memakan waktu sekitar 32 byte (karenanya 32 * 1000). Tapi kemudian ketika saya menjalankannya saya hanya perlu 804 (maka 196 * 32; mungkin runtime C memiliki bagian lain di stack yang harus Anda kurangi juga).


25

Bersenang-senang dengan pointer fungsi (tidak diperlukan TMP baru):

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

Sebagai catatan tambahan: Saya mengambil larangan terhadap persyaratan untuk memperluas ke operator logis dan relasional juga. Jika Anda mengizinkan negasi logis, panggilan rekursif dapat disederhanakan menjadi:

funcs[!!(limit-1)](x+1, limit-1);

Saya suka cara Anda mendapatkannya dengan bit shift. tetapi dengan penyederhanaan Anda sesudahnya, apa yang dilakukan double bang? itu bitwise atau logis? Saya tersesat dan google membuat saya berkeliling dalam lingkaranfuncs[!!(limit-1)](x+1, limit-1);
jon_darkstar

Saya lebih suka memiliki satu !dan beralih elemen array fungsi pointer, tapi saya tidak tahu apakah itu akan cocok dengan kegilaan Anda yang lain.
Chris Lutz

@ Chris: Saya setuju sepenuhnya - tapi saya tidak mempertimbangkan untuk menggunakan operator logis / relasi sampai setelah memposting, dan saya pikir tambalan satu baris akan lebih tepat. Selain itu, itu cocok sedikit lebih baik dengan seluruh nuansa masalah yang membingungkan.
Michael Burr

24

Saya merasa jawaban ini akan sangat sederhana dan mudah dimengerti.

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
Jawaban Anda menggunakan pernyataan kondisional, yang dilarang sesuai dengan pertanyaan.
stevelove

4
pernyataan kondisional adalah jika lain dll. Saya hanya menggunakan operasi logis !! Hpe sudah jelas!
Pappu

2
Bahkan dalam komentar Anda, Anda menulis "Jika ya maka panggil fungsi rekursif untuk mencetak". Sebuah kondisional yang ditulis dengan cara yang tidak jelas masih merupakan suatu kondisi. Default num juga merupakan persyaratan.
Gerry

23

Saya melewatkan semua kesenangan, semua jawaban C ++ yang bagus telah diposting!

Ini adalah hal yang paling aneh yang bisa saya lakukan, saya tidak akan bertaruh itu legal C99: p

#include <stdio.h>

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

Satu lagi, dengan sedikit kecurangan:

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

Ide terakhir, cheat yang sama:

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

Memanggil mainhasil dalam perilaku yang tidak terdefinisi seperti yang saya ingat.
Yakov Galka

4
Ini sangat legal C. @ybungalobill: Anda harus memikirkan C ++, di mana memanggil main () secara khusus tidak diperbolehkan.
Michael Foukarakis

@Michael: Mungkin, saya tidak terlalu mengenal C.
Yakov Galka

Saya pikir menggunakan Meningkatkan menyiratkan C ++. Apapun, pujian untuk solusi Boost.PP.
saya22

6
Operator logis &&dan ||kemungkinan akan jatuh di bawah "kondisi" karena mereka mengalami hubungan pendek (seperti yang akan terjadi ?:).
murah hati

22

Mudah seperti pie:

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

metode eksekusi:

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"

Spesifikasi tidak mengatakan bahwa urutan harus dihasilkan di dalam kode :)


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

Lebih banyak penyalahgunaan preprosesor:

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

Saya merasa sangat kotor; Saya pikir saya akan mandi sekarang.


2
Bisakah Anda menelepon A2()tanpa argumen seperti itu?
Chris Lutz

Saya ingin tahu tentang itu sendiri. Ini berfungsi baik dengan GCC, tapi saya tidak tahu apakah itu perilaku yang didefinisikan dengan baik.
keithmo

Didefinisikan dengan baik di C99, tidak ingat apa yang dikatakan C89, tidak menyebabkan masalah dengan setidaknya beberapa versi MSVC jika memori berfungsi.
zwol

15

Jika solusi POSIX diterima:

#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

Karena tidak ada batasan pada bug ..

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

Atau bahkan lebih baik (?),

#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
Anda harus menghindari optimisasi kompiler, untuk menjaga j yang tidak digunakan.
bandi

2
Dia hanya perlu menambah volatiledeklarasij
Patrick Schlüter
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.