Erstellen Sie ein Quadrat mit zunehmender Größe, indem Sie den ursprünglichen Code replizieren

45

Ihre Aufgabe ist es, ein Programm mit gerader Länge zu schreiben , das ein ASCII-Art-Quadrat (siehe unten) druckt und dessen Seitenlänge jedes Mal um 1 Einheit erhöht, wenn der ursprüngliche Quellcode in die Mitte des aktuellen Codes eingefügt wird.

Es fällt mir sehr schwer, diese Aufgabe gut zu definieren. Ich gebe Ihnen ein Beispiel:

  • Angenommen, Ihr ursprünglicher Code war CODEund er wurde gedruckt:

    0
    
  • Dann fügen Sie CODEin der Mitte ein: Ihr Code wird COCODEDEund es sollte gedruckt werden:

    00
    00
    
  • Neu einfügen CODEin der Mitte: Ihr Code wird COCOCODEDEDE und sollte drucken:

    000
    000
    000
    
  • Und so weiter. Ihre Antwort sollte theoretisch nach einer beliebigen Anzahl von Iterationen funktionieren, aber ich verstehe, dass sie aufgrund von Einschränkungen der Sprachleistung einen bestimmten Schwellenwert nicht vernünftig überschreiten kann.

Einige Regeln:

  • Sie können jedes druckbare ASCII (32-127) als Zeichen für Ihr Quadrat verwenden. Ihre Auswahl muss konstant sein (Sie sollten für jede Iteration dasselbe Zeichen verwenden).

  • Das Ausgangsquadrat muss die Seitenlänge 1 haben .

  • Ein Ascii-Art-Quadrat ist eine Zeichenfolge mit N Zeilen (getrennt durch N-1 Zeilenvorschübe / Zeilenumbrüche), wobei jede Zeile N Kopien des ausgewählten Zeichens enthält.

  • Ihre Ausgabe darf keine überflüssigen Leerzeichen enthalten, außer einem nachgestellten Zeilenumbruch.

  • Sie können die Standardeinstellungen für die Ein- und Ausgabe verwenden (Programme oder Funktionen sind zulässig, Snippets jedoch nicht).

  • Die Mitte Ihres Codes ist definiert als der Punkt, an dem der Quellcode in zwei Teile geteilt werden kann, sodass beide gleich sind.

  • Ihre Antworten werden nach der Länge Ihres ursprünglichen Programms in Byte bewertet. Die niedrigste Byteanzahl gewinnt. Bei Stimmengleichheit gewinnt die zuvor übermittelte Antwort.

  • Mit diesem Programm können Sie die Einfügungen anwenden, ohne dies von Hand tun zu müssen.


quelle
1
Ich muss zugeben, dass ich von dieser einfachen Frage , die ich zuvor gestellt habe, inspiriert war . Wenn die Leute denken, dass es zu eng ist, werde ich dies gerne löschen. Entschuldigen Sie auch, wenn ich Fehler gemacht habe, ich bin immer noch nicht zu erfahren mit den Regeln hier. :)
2
Willkommen bei PPCG! Ich schlage vor, die Sandbox für Ihre zukünftigen Herausforderungen zu verwenden.
user202729
7
Willkommen auf der Seite! Hervorragende Nutzung einer weiteren Herausforderung zur Inspiration, ohne in die Falle zu tappen :)
Shaggy
Ihr Hilfsprogramm funktioniert nicht bei Programmen mit mehreren Zeilen. Wie wäre es mit dieser modifizierten Version aus der anderen Frage?
Jo King
1
@ user77954 Aber mein Brainfuck-Code ist kürzer als dein Python :( (hat das schon mal jemand gesagt?)
Jo King

Antworten:

41

Pyth , 2 Bytes


5

Probieren Sie es online! Auch Versuchen Sie es verdoppelt , verdreifacht !

Wie funktioniert das?

\nist der Befehl, der sein Argument mit einem hinteren Newline druckt, während er zurückgespielt gleichzeitig. Jedes Mal, wenn Sie eine Einfügung vornehmen, verwandeln Sie das Ganzzahlliteral 5 in eine Zahl, die N Kopien von 5 verketteten Zeilen enthält. Die führenden Zeilen stellen im Grunde genommen sicher, dass sie so oft gedruckt werden, dass sie quadratisch bleiben.

Mr. Xcoder
quelle
6
Holy Frick, das ist kurz ...
ETHproductions
Beweis der Optimalität (: P): Da die Byteanzahl gerade sein muss und nicht negativ sein darf, beträgt die minimal mögliche Byteanzahl 0 Bytes. Es gibt genau 1 Programm mit 0 Bytes, das die Aufgabe nicht erfüllt. Daher sind 2 Bytes optimal.
Mr. Xcoder
10
Jeder (insbesondere HNQ-Wähler) stimmt anderen Antworten zu und vermeidet den FGITW-Effekt.
User202729
25

JavaScript (ES6), 42 32 30 Byte

s=[this.s]+0;  console.log(s);

Zweite Iteration:

s=[this.s]+0;  s=[this.s]+0;  console.log(s);console.log(s);

Dies funktioniert durch ein Anhängen 0zu sjeder Zeit in der ersten Hälfte des Codes ausgeführt wird , und das Drucken sselbst jedes Mal die zweite Hälfte ausgeführt wird . Nutzt vier Macken von JavaScript:

  1. Auf die aktuelle Umgebung kann mit verwiesen werden this. Dies ermöglicht es uns, this.sanstelle von zu tun s.
  2. Wenn auf eine Eigenschaft zugegriffen wird, die nicht für ein Objekt definiert wurde, gibt JavaScript zurück, anstatt einen Fehler auszulösen undefined.
  3. Ein Array plus eine Zahl gibt eine Zeichenfolge zurück. [1,2,3] + 4 === "1,2,34"
  4. Wird beim Stringing eines Arrays undefinedin die leere Zeichenfolge konvertiert, was bedeutet, dass [undefined] + 0 === "0".

Zusammengenommen bedeutet dies, dass wir die erste Hälfte (die eine Folge von Nullen erzeugt) in nur 13 Bytes ausdrücken können. Wenn die Verwendung von alertanstelle von console.logzulässig ist, können 4 weitere Bytes durch Verkürzen der zweiten Hälfte eingespart werden.

ETHproductions
quelle
Herzlichen Glückwunsch, besteht die Tests, die ich gemacht habe!
1
... Genial! :)
Shaggy
17

Python 2 , 42 38 28 Bytes

id='%s@'%id  ;print id[22:];

Probieren Sie es online! . Sie können auch die 2. und 3. Iteration ausprobieren

Stange
quelle
Äh ... Zeichen, keine Zeichenfolge.
user202729
@ user202729 danke für die Köpfe nach oben, behoben =]
Rod
13

Python 2 , 22 Bytes

i=0;i+=1; i
print'*'*i

Probieren Sie es online!

Verdoppelt:

i=0;i+=1; ii=0;i+=1; i
print'*'*i
print'*'*i

Beachten Sie, dass die zweite Hälfte mit einem Zeilenumbruch beginnt.

xnor
quelle
9

C (gcc) , 170 168 96 80 72 70 Bytes

Viel kürzere Version. Ich wünschte immer noch, ich könnte eine Lösung ohne den Präprozessor finden.

i;main(n){for(;i++<n;)printf
#if 0

#endif
(" %*c",n=__LINE__/4, 10);}

Probieren Sie es online!

Alte 168-Byte-Version:

#ifndef A
#define A p(c){putchar(c);}j,n;main(i){for(
#else
#define A n++,
#endif
A



#ifndef B
#define B i=++n;i--;p(10))for(j=n;j--;)p(64);}
#else
#define B
#endif
B

Probieren Sie es online!

Gastropner
quelle
@ user202729 ah ja. Dachte, ich habe einen Tippfehler behoben, aber einen Fehler eingeführt. Zurückkehren.
Gastropner
8

Python 2 , 30 Bytes

False+=1      ;print'*'*False;

Probieren Sie es online! , 2. und 3. Iteration

Dies macht sich die Tatsache zunutze, dass Bools in Python im Grunde genommen Ints und die Namen sind Falseund Truein Python 2 neu zugewiesen werden konnten.

Python 1 , 32 Bytes

exit=exit+'*'  ;print exit[30:];

Probieren Sie es online! , 2. und 3. Iteration

In Python 1 existierten die eingebauten Zeichenfolgen exitund quit, um den Benutzer der interaktiven Shell darüber zu informieren, wie sie beendet werden kann. Der Standardwert ist "Use Ctrl-D (i.e. EOF) to exit.".

ovs
quelle
1
Ich wollte vorschlagen n=False+=1;print'*'*n;, aber ich vergesse immer wieder, dass dies kein Python-Feature ist ...
ETHproductions
6

Holzkohle , 6 Bytes

⊞υωLυ⸿

Probieren Sie es online! Erläuterung:

  ω     Predefined empty string (any variable would do here)
 υ      Predefined initially empty list
⊞       Push

υ endet mit einer Länge der Anzahl der Wiederholungen.

    υ   List
   L    Length
        Implicitly print as a row of `-`s
     ⸿  Move to start of next line
Neil
quelle
6

Haskell , 68 Bytes

let s@(z:n)="0\n"in case lines<$>[]of(h:t):_->(h:h:t)>>(z:h++n);_->s

Probieren Sie es einmal , zweimal oder dreimal online aus .

Wegen Haskells Faulheit zählt ein Ausdruck wie der oben genannte als eine Funktion, die gemäß dieser Meta-Frage keine Argumente akzeptiert .

Laikoni
quelle
5

Brain-Flak , 74 Bytes

(((((()()()){}){}){}){})((()()()()()<>){})<>([]){({}[()]<(({})<>)<>>)}{}<>

Probieren Sie es online!

Versuchen Sie es verdoppelt und verdreifacht .

Erläuterung

(((((()()()){}){}){}){}) # push 48 ("0") onto first stack
((()()()()()<>){})       # push 10 (\n) onto second stack
<>([]){({}[()]<          # a number of times equal to the height of the first stack:
  (({})<>)<>             #   copy the top of the first stack to the second stack
>)}{}<>                  # cleanup and return to second stack

Der Haltepunkt befindet sich in der Mitte des <>Abschnitts "Push 10". Wird dies aufgebrochen, verbleibt eine 5 auf dem dritten Stapel, bis die entsprechende zweite Hälfte erreicht ist. An diesem Punkt wird das Drücken von 10 genau dort fortgesetzt, wo es aufgehört hat.

Während es möglich ist, einen druckbaren ASCII-Wert (Leerzeichen) in 22 Bytes zu verschieben, würde dies dazu führen, dass die Zentrale <>nach dem Verschieben ausgeführt wird 5. Durch das Hinzufügen von zwei weiteren Bytes konnte ich das verschieben, <>sodass der gesamte Fortschritt in Richtung Push 10auf dem dritten Stapel lag. Als Bonus machte dies auch das resultierende Quadrat ästhetisch ansprechender.

Nitrodon
quelle
4

tinylisp , 112 Bytes

(load library) (d N((q((x)(i x(inc x)1)))(v(h(t(t(h(t(q())))))))))(join(repeat-val(string(repeat-val 42 N))N)nl)

Probieren Sie es online! Auch verdoppelt und fünffach .

Der Ansatz "Eine Zeichenfolge in der ersten Hälfte erstellen und in der zweiten Hälfte drucken", den viele Sprachen verwenden, funktioniert in tinylisp nicht, da es keine veränderbaren Variablen gibt. Stattdessen führen wir einige ernsthafte Code-Verschachtelungen durch.

Wenn eine zweite Kopie des Codes eingefügt wird, wird sie in das eingefügt (q()), wodurch sie in eine Liste eingeschlossen wird. Dann (h(t(t(h(t(...))))))bohrt in diese Liste das Teil nach (d N. (v(...))bewertet es; dann übergeben wir es an die unbenannte Funktion (q((x)(i x(inc x)1))), die den resultierenden Wert erhöht, wenn es sich um eine Zahl handelt, und 1 zurückgibt, wenn es sich um die leere Liste handelt. Das Endergebnis in der äußersten verschachtelten Version des Codes wird zugewiesen N. Im Wesentlichen haben wir eine seltsame Art von Rekursion eingerichtet, die die Anzahl der Verschachtelungsebenen zählt.

Die zweite Hälfte des Codes erstellt dann eine NSternchenfolge, dann eine Liste Nsolcher Zeichenfolgen und schließt sich dann der Liste in Zeilenumbrüchen an. Das Ergebnis wird mit einem nachgestellten Zeilenumbruch angezeigt.

DLosc
quelle
3

R , 44 Bytes

F=F+1;T=TRUE*TRUE+12;
write(strrep(1,F),"");

Probieren Sie es online!

Druckt mit einem nachgestellten Zeilenumbruch. Das T=TRUE*TRUE+12ist nur zum Auffüllen der Länge.

Versuchen Sie es verdoppelt und versuchen Sie es verdreifacht .

Giuseppe
quelle
Sie können 2 Bytes entfernen, indem Sie die Semikolons löschen. Ich nehme an, es gibt ein Leerzeichen am Ende der ersten Zeile, das Sie durch ein # ersetzen können: F=F+1;T=TRUE*TRUE+12#<newline>write(strrep(1,F),"")
Andreï Kostyrka
@ AndreïKostyrka das wären 43 bytes das ist leider nicht mal so.
Giuseppe
3

Julia 0,6 , 29 Bytes

Alle meine Ideen waren länger als die Anpassung der cleveren Python-Lösung von xnor.

i=0;i+=1;    i
println("0"^i)

Wird

i=0;i+=1;    ii=0;i+=1;    i
println("0"^i)
println("0"^i)

Probieren Sie es online!

gggg
quelle
3

SNOBOL4 (CSNOBOL4) , 130 68 Bytes

Jetzt ohne Kommentare! Eine Erklärung des alten Algorithmus finden Sie im Bearbeitungsverlauf .

	X =X + 1
	A =ARRAY(X,DUPL(1,X));
I	I =I + 1
	OUTPUT =A<I>	:S(I)
END

Probieren Sie es online!

Probieren Sie es doppelt und verdreifacht

Erläuterung:

	X =X + 1		;* increment X
	A =ARRAY(X,DUPL(1,X));	;* create an x-length array with 1 repeated x times for each element
I	I =I + 1		;* for i < x
	OUTPUT =A<I>	:S(I)	;* output a[i]
END

Weil ein ENDEtikett erforderlich ist und alles nach dem erstenEND Ignorieren Etiketts erfolgt, bieten sich für diese Herausforderung zwei Vorteile:

  • Operationen in der ersten Hälfte des Programms werden Xfür die XWiederholungen wiederholt
  • es wird (für den Dolmetscher) nur eine Kopie der zweiten Hälfte geben, einschließlich Etiketten .

Dies legt nahe, dass wir die Wiederholung für die erste Hälfte verwenden und dann einen "konventionelleren" Etikettierungsansatz verwenden können, um die Ausgabezeiten zu wiederholen X.

Die erste Hälfte ist

	X =X + 1
	A =ARRAY(X,DUPL(1,X));

Wenn dies wiederholt wird, wird Xdie entsprechende Anzahl erhöht und ein ARRAY Amit Indizes von 1bis erstellt, Xwobei jedes Element Ader Zeichenfolge 1wiederholt wirdX Male ist.

Unabhängig davon, wie oft das Programm wiederholt wird, sieht der Interpreter nur:

I	I =I + 1
	OUTPUT =A<I>	:S(I)
END

Dies ist ein typisches SNOBOL-Programm, das die Elemente Anacheinander ausgibt, bis der Index überschritten wird, und dann das Programm beendet.

;ist ein optionaler Zeilenabschluss, der normalerweise für einzeilige EVALoder CODEAnweisungen reserviert ist , der die Byteanzahl auf 68 bringt und den halben Punkt markiert, sodass der Code dort angehängt werden kann.

Giuseppe
quelle
1

Zsh , 10 Bytes

s+=0
<<<$s

Probieren Sie eine vollständige Testsuite online aus!

... ja, das ist ein bisschen besser. N-mal an die Zeichenfolge anhängen und dann N-mal drucken. Es stellt sich heraus, <<<foo<<<foofunktioniert gut.


Zsh , 64 Bytes

Verwendetes Zeichen: (Leerzeichen).

f(){printf '%*s\n' $1}
:<<'E'

E
repeat $[i=LINENO/3];f $i
exit

Probieren Sie eine vollständige Testsuite online aus!

Der Mittelpunkt liegt zwischen der zweiten Eund der darauf folgenden Newline. Ein Heredoc endet, wenn sich Ein einer eigenen Zeile ein befindet, was genau in der Mitte des Codes geschieht.

GammaFunktion
quelle
lol @ "leichte" Verbesserung. könnte es auch ausdrücken alss+=0;<<<$s
roblogic