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.
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>structNumberGeneration{staticvoidout(std::ostream& os){NumberGeneration<N-1>::out(os);
os << N << std::endl;}};template<>structNumberGeneration<1>{staticvoidout(std::ostream& os){
os <<1<< std::endl;}};int main(){NumberGeneration<1000>::out(std::cout);}
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:
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?" :)
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
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 copyist 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 recursiontemplate<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(){staticint 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. ]]
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 :)
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:
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)
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.
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.
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.
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>staticint current =1;structprint{print(){ std::cout << current++<< std::endl;}};int main(){print numbers [1000];}
#include<stdio.h>#defineOut(i) printf("%d\n", i++);#define REP(N) N N N N N N N N N N
#defineOut1000(i) REP(REP(REP(Out(i))));void main(){int i =1;Out1000(i);}
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!
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);return0;}
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.
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();}
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>usingnamespace std;int num(){staticint i =1;return i++;}int main(){ generate_n(ostream_iterator<int>(cout,"\n"),1000, num);}
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>staticvoid print_line(int i){
printf("%d\n", i);
print_line(i+1);}int main(int argc,char* argv[]){//get up near the stack limitchar 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).
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:
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 printreturn num<1000&& print1000(++num);}int main(){
print1000();return0;}
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,~));}
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.
printf
und jedes Mal zwei Nummern zu drucken, nein?:?
ist keine bedingte Aussage (es ist ein Ausdruck) ...Antworten:
Zeitrekursion kompilieren! : P.
quelle
'\n'
sei denn, Sie möchten wirklich spülen, verwenden, es++i
sei denn, Sie benötigen tatsächlich den früheren Wert voni
, alsconst
Referenz ü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.Dieser kompiliert tatsächlich zu einer Assembly, die keine Bedingungen hat:
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:
quelle
j
liegt es zunächst1
daran, dass es tatsächlichargc
so ist,1
wenn das Programm ohne Argumente aufgerufen wird. Dannj/1000
ist0
bisj
wird1000
, danach ist es1
.(exit - main)
ist natürlich der Unterschied zwischen den Adressen vonexit()
undmain()
. Das heißt(main + (exit - main)*(j/1000))
istmain()
bisj
wird1000
, danach wird esexit()
. Das Endergebnis ist, dassmain()
es aufgerufen wird, wenn das Programm gestartet wird, sich dann beim Inkrementieren 999 Mal rekursivj
aufruft und dann aufruftexit()
. Puh :)Ich bin überrascht, dass niemand dies gepostet zu haben scheint - ich dachte, es wäre der offensichtlichste Weg.
1000 = 5*5*5*8.
quelle
Sieht so aus, als müssten keine Schleifen verwendet werden
quelle
copy
Betrug istprintf
es eine Schleife gibt: pcopy
ist Betrug"Hier sind drei Lösungen, die ich kenne. Der zweite könnte jedoch argumentiert werden.
[ 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. ]]
quelle
Ich schreibe die printf-Anweisung nicht 1000 Mal!
Bitte ;)
quelle
$r='printf("'; for (1..1000) { $r.="$_\\n" } $r.='");'; print $r;
Es werden nicht alle Zahlen gedruckt , aber "Zahlen von 1 bis 1000 drucken ". Mehrdeutige Frage zum Sieg! :) :)
quelle
print "Print numbers from 1 to 1000."
- mehrdeutige Frage für den Sieg, ungenaue Beschreibungen saugen :)Lösen Sie einen schwerwiegenden Fehler aus! Hier ist die Datei countup.c:
Kompilieren und dann an einer Shell-Eingabeaufforderung ausführen:
Dies druckt tatsächlich die Zahlen von 1 bis 1000 ohne Schleifen oder Bedingungen!
quelle
\n
dies ausreicht, um die Ausgabe zu leeren.Verwenden von Systembefehlen:
quelle
/usr/bin/seq
verwendet intern eine Schleife. :)seq
Dienstprogramm hat (im Standard-Setup)? <system("/bin/echo {1..1000}");
Wenn Sie nur den Unit-Test zuerst geschrieben hätten ...Ungetestet, sollte aber Vanille Standard C sein:
quelle
<
ist keine Bedingung. Es ist ein relationaler Operator.if
/else
ist 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.cmpl
,setle
, undmovzbl
. x86-64 ist das plus acltq
. PowerPC besteht aus 2 Anweisungen:cmpwi
undcrnot
.1 - i / 1000
. Keine Vergleiche!Ein bisschen langweilig im Vergleich zu anderen hier, aber wahrscheinlich das, wonach sie suchen.
quelle
&&
Bewertung in der ersten Zeile von nutzenf()
.Die Aufgabe hat nie angegeben, dass das Programm nach 1000 beendet werden muss.
( Kann verkürzt werden, wenn Sie ./a.out ohne zusätzliche Parameter ausführen. )
quelle
rand()
, werden wir alle Zahlen von 1 bis 1000 drucken. Schließlich =: PEinfach wie Torte! : P.
quelle
quelle
Wir können 1000 Threads starten, von denen jeder eine der Zahlen druckt. Installieren Sie OpenMPI , kompilieren Sie mit
mpicxx -o 1000 1000.cpp
und führen Sie es mit ausmpirun -np 1000 ./1000
. Sie müssen wahrscheinlich Ihr Deskriptorlimit mitlimit
oder erhöhenulimit
. Beachten Sie, dass dies ziemlich langsam ist, es sei denn, Sie haben viele Kerne!Natürlich werden die Nummern nicht unbedingt in der richtigen Reihenfolge gedruckt, aber die Frage erfordert nicht, dass sie bestellt werden.
quelle
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.Mit einfachem C:
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.quelle
B
ist 1000 eine vollkommen gültige Zahl und immer gleichB^3
.Verwenden Sie einfach std :: copy () mit einem speziellen Iterator.
quelle
std::copy
die implizite Bedingung in deroperator !=()
. 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.Funktionszeiger (ab) verwenden. Keine Präprozessor-Magie zur Steigerung der Ausgabe. ANSI C.
quelle
quelle
Hässliche C-Antwort (nur für einen Stapelrahmen pro Zehnerpotenz abgewickelt):
quelle
Paketüberfluss:
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).
quelle
Spaß mit Funktionszeigern (keiner der neuen TMPs benötigt):
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:
quelle
funcs[!!(limit-1)](x+1, limit-1);
!
und wechsle die Funktionszeiger-Array-Elemente, aber ich weiß nicht, ob das gut mit deiner anderen Verrücktheit zusammenpasst.Ich denke, diese Antwort wird sehr einfach und leicht zu verstehen sein.
quelle
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
Ein anderer mit ein wenig Betrug:
Letzte Idee, gleicher Cheat:
quelle
main
führt zu undefiniertem Verhalten, wie ich mich erinnere.&&
und||
würden wahrscheinlich unter "Bedingungen" fallen, da sie (wie?:
) kurzschließen .Einfach wie Torte:
Ausführungsmethode:
Die Spezifikation besagt nicht, dass die Sequenz innerhalb des Codes generiert werden muss :)
quelle
quelle
quelle
Mehr Präprozessor-Missbrauch:
Ich fühle mich so schmutzig; Ich denke, ich gehe jetzt duschen.
quelle
A2()
ohne ein solches Argument anrufen ?Wenn POSIX-Lösungen akzeptiert werden:
quelle
Da es keine Einschränkung für Bugs gibt ..
Oder noch besser (?),
quelle
volatile
die Erklärung vonj