Sierpinskified Code

47

Schreiben Sie einen rechteckigen Textblock, der bei Anordnung in einem Sierpinski-Teppich unter Verwendung gleich großer Leerzeichenblöcke für die leeren Teile ein Programm erstellt, das die Iterationsnummer des Teppichs ausgibt.

Zum Beispiel, wenn Ihr Textblock ist

TXT
BLK

Führen Sie dann das Programm aus

TXTTXTTXT
BLKBLKBLK
TXT   TXT
BLK   BLK
TXTTXTTXT
BLKBLKBLK

sollte ausgegeben werden, 1da die Form des Programms die erste Iteration des Sierpinski-Teppichs darstellt.

Ebenso läuft

TXTTXTTXTTXTTXTTXTTXTTXTTXT
BLKBLKBLKBLKBLKBLKBLKBLKBLK
TXT   TXTTXT   TXTTXT   TXT
BLK   BLKBLK   BLKBLK   BLK
TXTTXTTXTTXTTXTTXTTXTTXTTXT
BLKBLKBLKBLKBLKBLKBLKBLKBLK
TXTTXTTXT         TXTTXTTXT
BLKBLKBLK         BLKBLKBLK
TXT   TXT         TXT   TXT
BLK   BLK         BLK   BLK
TXTTXTTXT         TXTTXTTXT
BLKBLKBLK         BLKBLKBLK
TXTTXTTXTTXTTXTTXTTXTTXTTXT
BLKBLKBLKBLKBLKBLKBLKBLKBLK
TXT   TXTTXT   TXTTXT   TXT
BLK   BLKBLK   BLKBLK   BLK
TXTTXTTXTTXTTXTTXTTXTTXTTXT
BLKBLKBLKBLKBLKBLKBLKBLKBLK

sollte 2 ausgeben, da dies die Form der zweiten Sierpinski-Teppichiteration ist.

Ausführen des Textblocks wie er ist

TXT
BLK

sollte ausgegeben werden, 0da dies als nullte Iteration angesehen werden kann.

Dies sollte für alle weiteren Iterationen funktionieren. (Zumindest theoretisch, vorausgesetzt, der Computer hat den Speicher und alles.)

Einzelheiten

  • Programme können möglicherweise keine Informationen über ihren Quellcode lesen oder darauf zugreifen. Behandle dies wie eine strenge Herausforderung für Quine.
  • Die Ausgabe erfolgt an stdout oder eine ähnliche Alternative. Geben Sie nur die Nummer und einen optionalen Zeilenumbruch aus. Es erfolgt keine Eingabe.
  • Der Textblock kann beliebige Zeichen enthalten, die nicht als Zeilenendezeichen gelten . Der Textblock darf Leerzeichen enthalten.
  • Der "leere Raum" im Teppich muss vollständig aus Leerzeichen bestehen .
  • Sie können optional davon ausgehen, dass alle Programme einen nachgestellten Zeilenumbruch haben.

Sie können dieses Stapel-Snippet verwenden, um bei jeder Iteration einen Teppich für einen bestimmten Textblock zu generieren:

<style>#o,#i{font-family:monospace;}</style><script>function c(e){e=e.split("\n");for(var n=new Array(3*e.length),t=0;t<n.length;t++){var l=t%e.length;n[t]=e[l]+(t>=e.length&&t<2*e.length?e[l].replace(/./g," "):e[l])+e[l]}return n.join("\n")}function f(){for(i=document.getElementById("i").value,n=parseInt(document.getElementById("n").value);n>0;)i=c(i),n--;document.getElementById("o").value=i}</script><textarea id='i'placeholder='code block...'rows='8'cols='32'></textarea><br>Iterations <input id='n'type='text' value='1'><br><br><button type='button'onclick='f()'>Generate</button><br><br><textarea id='o'placeholder='output...'rows='8'cols='32'style='background-color:#eee'readonly></textarea>

Wertung

Die Einsendung, deren anfänglicher Textblock flächenmäßig am kleinsten ist (Breite mal Höhe), gewinnt. Das TXT\nBLKBeispiel ist 3 mal 2 für eine Punktzahl von 6. (Grundsätzlich gewinnt der kürzeste Code, daher der Code-Golf-Tag.)

Tiebreaker geht zu dem Beitrag über, der die wenigsten unterschiedlichen Zeichen in seinem Textblock verwendet. Wenn immer noch unentschieden, antworte zuerst und gewinne.

Calvins Hobbys
quelle

Antworten:

23

CJam, 9 Bytes

Ich denke, das kann verbessert werden, aber jetzt können wir damit anfangen ...

];U):U8mL

Wie es funktioniert :

];             "Wrap everything on stack in an array and discard it";
               "Before this point, the only thing on array can be the log 8 result of";
               "last updated value of U, or nothing, if its the first code";
  U):U         "Increment by 1 and update the value of U (which is pre initialized to 0)";
      8mL      "Take log base 8 of U. This is the property of Sierpinski carpet that";
               "the occurrence of the code is 8 to the power iteration count, indexed 0";

Probieren Sie es hier online aus

Optimierer
quelle
35

piet - 32 * 6 = 192

Bildbeschreibung hier eingeben

Ich füllte den leeren Raum mit dem Schachbrettmuster. Ich denke, das macht den Sierpinski ein bisschen dreister.

Hier ist die zweite Iteration: Bildbeschreibung hier eingeben

original: 32 * 7

Bildbeschreibung hier eingeben

captncraig
quelle
19

> <> , 11 * 2 = 22

";n"00pbi1v
+$3*:@3-0.>

Hier verfolgen wir einen anderen Ansatz, indem wir die Sprung- / Teleport-Funktionalität von> <> verwenden.

Das Programm führt nur Sätze in der obersten Zeile aus, wobei der 1./2. Satz, dann der 3./2. Satz, der 9./10. Satz, der 27./28. Satz usw. ausgeführt werden (in Potenzen von 3). Da die oberste Zeile 3^nBlöcke enthält, werden nur nBlöcke ausgeführt, bevor das Programm zum Start zurückkehrt, den oberen Teil des Stapels ausgibt und anhält (aufgrund der nAnweisung, die über platziert wurde p).

Das Programm nutzt die Regel "Es gibt keine Eingabe.", Da der iBefehl -1 auf den Stapel legt, wenn EOF erfüllt ist. Um dies zu testen, müssen Sie eine leere Datei einfügen.


Vorherige Einreichung, 7 * 4 = 28

l"v"10p
v>:1=?v
3  ;n{<
<^}+1{,

Die erste Zeile verschiebt kontinuierlich die Länge des Stapels für jeden Block und ändert das erste "Anführungszeichen vmit dem pBefehl put in einen Abwärtspfeil. Nach Ablauf der ersten Zeile sieht der Stapel wie folgt aus

[0, 1, 2, .., 3^n]

(Beachten Sie, dass die Initiale lzweimal verwendet wird.)

Die letzten drei Zeilen zählen dann, wie oft wir durch 3 teilen müssen, bevor wir 1 drücken (da> <> keine Protokollfunktion hat). Die untere Null wird verwendet, um die Zählung zu verfolgen.

Sp3000
quelle
13

Perl, 26

$_+=.91/++$n;
die int."\n";

Hierbei wird die harmonische Reihe verwendet, um den Logarithmus zur Basis 3 zu approximieren. Ich denke, es funktioniert, aber ich habe es nur für kleine Zahlen versucht. Dank squeamish Ossifrage für die Idee der Verwendung die.

Alte Version (34):

$n--or$n=3**$s++;
print$s-1if!$o++;
grc
quelle
Das ist sehr ordentlich!
Squeamish Ossifrage
10

Perl, 30 (15 × 2)

Zunächst einmal behaupte ich, dass 10 Iterationen eine vernünftige Grenze darstellen und nicht 2 32 . Nach 10 Iterationen wird ein Programm, das aus N Bytes besteht, auf ( N × 3 20 ) Bytes (plus Zeilenumbrüche) erweitert, was selbst für N = 1 über 3 Gigabytes liegt . Eine 32-Bit-Architektur kann 11 Iterationen überhaupt nicht verarbeiten. (Und offensichtlich gibt es nicht genug Teilchen im Universum für 2 32 Iterationen).

Also hier ist meine Lösung:

$n++; $_=log$n;
print int;exit;

Dies funktioniert, indem die Variable $nin der ersten Zeile erhöht und bei jedem Schritt der Logarithmus berechnet wird. Die zweite Zeile gibt den ganzzahligen Teil dieses Logarithmus aus und wird beendet.

Ein einfacher Logarithmus zur Basis e (2.718 ..) ist nahe genug, um korrekte Ergebnisse für die ersten 10 Iterationen zu liefern.

zimperliches Ossifrage
quelle
2
Laut OP sollte es theoretisch für alle Iterationen funktionieren.
Nathan Merrill
2
@ NathanMerrill Nun, OK. Aber um die ursprüngliche Spezifikation einzuhalten, hätte es auch in alternativen Universen funktionieren müssen. Die Frage wurde seitdem bearbeitet.
Squeamish Ossifrage
Ich habe die Frage wegen der hier gemachten guten Punkte geändert. Ich bin damit einverstanden , dass natürliche Logarithmus verwendet ist eher eine Grauzone, aber ehrlich gesagt bin ich nicht allzu besorgt , da dies nicht gewinnt.
Calvins Hobbys
Die meisten dieser Einreichungen behalten die Kontrolle nur in der obersten Reihe von 3 ^ nx 1 Kacheln. Wenn Sie nur dieses Segment des Teppichs erzeugen, können Sie einiges weiter skalieren. Mit ziemlicher Sicherheit dahin, wo Rundungsfehler Sie stören werden.
Captncraig
1
Wie ich bereits erwähnte, wurde in der ursprünglichen Frage nach Code gefragt, der auf eine "angemessene" Anzahl von Iterationen skaliert werden kann (bis zu 2 ^ 32) . Wenn Sie rechnen, werden Sie feststellen, dass selbst ein einzelnes Byte nach so vielen Iterationen auf mehr als 10 ^ 4098440370 Bytes erweitert wird. Ich schlug vor , eine Antwort , dass ich dachte , war ein bisschen mehr sinnvoll , aber seitdem das Wort „angemessen“ ist von der Frage verschwunden: - /. Schau, ich bin hier fertig. Stimmen Sie diese Antwort einfach ab, wenn Sie sie nicht mögen.
Squeamish Ossifrage
9

Golfscript 9 * 2 = 18

0+       
,3base,(}

(Beachten Sie, dass die erste Zeile abschließende Leerzeichen enthält, um sie rechteckig zu machen.)

Ich konnte keine Protokollfunktion für Golfscript finden und basemusste dies tun.

Golfscript beginnt mit einer leeren Saite. Erhöht also 0+die Länge der Saite um 1 (durch Coversion). Bis die erste Zeile beendet ist, wird der Stapel eine Zeichenfolge von Länge haben 3^n, die wir zur Log-Basis 3 nehmen, bevor wir einen Superkommentar abgeben. nwird dann automatisch ausgedruckt.

Sp3000
quelle
Sie können 2 Zeichen speichern, indem Sie eine Ganzzahl anstelle einer Zeichenfolge verwenden und daher die Zeichen ,in der zweiten Zeile speichern . Erste Zeile 0or):; zweite Zeile 3base,(}. Das andere offensichtliche Ziel ist das (in der zweiten Zeile. Dies ist schwieriger, kann aber auch durch Ersetzen der ersten Zeile 1+~abs(durch ein 7 * 2-Rechteck behoben werden.
Peter Taylor
8

C, 12 × 8 = 96

Inspiriert von @ciamej, habe ich es reduziert. Es verwendet diesen Trick zum Teilen durch 3 und die Erkenntnis, dass der Teppich ein Wenn effektiv in eine While-Schleife umwandelt.

Der Code wurde unter gcc / Ubuntu auf Iterationen bis zu 3 getestet.

#ifndef A //
#define A //
x;main(a){//
a++;/*    */
if(a/=3)x++;
printf(   //
"%d",x);} //
#endif    //

Vorherige Lösung: C, 11x12

Kein Größengewinner, aber hey, es ist C.

Es findet log2 der Blockanzahl durch Bitverschiebung und verwendet dann einige magische Zahlen und Int-Kürzungen, um log3 zu schätzen. Die Mathematik sollte bis zu 26 Iterationen (eine 42-Bit-Zahl) verarbeiten.

#ifndef A//
#define A//
int n=0;//_
int main//_
(v,c){//___
n+=1;/*..*/
while(n//__
>>=1)v++;//
n=.3+.62*v;
printf(//__
"%d",n);}//
#endif//__
Ahelly
quelle
Hallo, ich habe eine gekürzte Version Ihrer Lösung veröffentlicht.
Dienstag,
Netter Trick damit wenn! ;)
ciamej
6

CJam, 9 Bytes

Die Idee für die Verwendung ]stammt von Optimizer, es wird jedoch eine ganz andere Methode zum Zählen verwendet.

X~]:X,8mL

Probieren Sie es online aus

Wie es funktioniert:

X~          "push X and dump its contents.  On the zeroth iteration, X is a single number, but later is it an array.";
  ]         "wrap everything into an array.  The stack would contain the contents of X plus the result of the previous instance of the code";
   :X       "store this array back into X.  X is now 1 element longer";
     ,      "take the length of X";
      8mL   "do a base-8 logarithm of it";

Zwei weitere 9-Byte-Lösungen

]X+:X,8mL

],X+:X8mL
PhiNotPi
quelle
Dies verbindet Optimizer sogar mit dem Tiebreaker. : P Tiebreakerbreaker: früherer Beitrag gewinnt.
Calvins Hobbys
Ich denke, es ist trotzdem eine gute Lösung. Ich habe 9 Zeichen nicht geschlagen.
PhiNotPi
Ich denke, der allgemeine Ansatz ist nur derselbe (und der einzige Ansatz, der Sinn macht) - Habe eine Variable, inkrementiere sie irgendwie um 1.
Optimierer
4

Python 2, 15 * 3 = 45

m=n=0;E=exit  ;
m+=1;n+=m>3**n;
print n;E()   ;

Eine weitere Implementierung der Idee von Count-First-Row-Then-Log-Three-And-Exit. Kann wohl noch ein bisschen mehr golfen werden.

Sp3000
quelle
2

bc, 2 · 16 + 1 = 33

Das zusätzliche +1 in der Punktzahl ist, weil die -lOption bc erforderlich ist:

a+=1;          
l(a)/l(3);halt;
Digitales Trauma
quelle
2

Golfscript, 7 * 2 = 14

1+~abs(
3base,}

Dies ist inspiriert von der Antwort von Sp3000 und insbesondere von dem Wunsch, die lange zweite Leitung zu optimieren. 3base,ist so kurz wie ein Logarithmus zur Basis 3 in GS, und der Superkommentar }ist eindeutig optimal.

Was für die erste Zeile erforderlich ist, ist die Zuordnung der leeren Zeichenfolge ''vom anfänglichen stdin zu 0 und anschließend die Zuordnung jeder nicht negativen Ganzzahl zu ihrem Nachfolger. Auf diese Weise beenden wir die erste Zeile mit 3^n - 1auf dem Stapel und 3base,benötigen keine Dekrementierung.

Peter Taylor
quelle
2

C, 13 × 8

#ifndef A//__
#define A//__
x;a;main(){//
a++;;;;;;;;;;
while(a/=3)//
x++;printf(//
"%d",x);}//__
#endif//_____
ciamej
quelle
1

Perl, 76

Ich weiß, dass es wahrscheinlich nicht sinnvoll ist, dies zu veröffentlichen, da es bereits gründlich durchgearbeitet wurde, aber hier ist trotzdem meine aktuelle Lösung.

$_++;                                 
if(not$_&$_-1){print log()/log 8;$_--}
PhiNotPi
quelle
@Alex Das scheint auch bei der ersten Iteration nicht zu funktionieren.
PhiNotPi
Ja, es funktioniert so wie es ist. Hast du deine Methode getestet?
PhiNotPi
Meins funktioniert auf ideone: ideone.com/othumP .
PhiNotPi
Erwischt. Ich habe ein wichtiges Detail verpasst, das bisher nicht funktioniert hat. Du hast recht, mein Vorschlag ist falsch.
Alex A.
1

> <> (Fisch), 12 * 3 = 36

Eine einfachere> <> Lösung:

'v'00p0l1+  
>  :2-?v$1+v
^$+1$,3< ;n<

Wir laufen zuerst die oberste Reihe der oberen Blöcke. 'v'00pSetzt vden Programmzeiger an die allererste Position des gesamten Programms und richtet ihn nach unten, wenn er nach Erreichen des Zeilenendes wieder zum Anfang zurückkehrt. Davor schiebt jeder Block 0 und die Länge des Stapels + 1 darauf. (Stapel wird sein 0 2 0 4 0 6 ...)

In der ersten Hälfte der zweiten und dritten Hälfte zählen wir, wie oft wir das obere Stapelelement teilen können, bevor wir 2 erhalten (wir speichern dies im zweiten bis oberen Element).

Am Ende geben wir das zweitoberste Element des Stapels aus.

randomra
quelle
1

Lua, 3 · 17 = 51

Gleiche Strategie wie die meisten Leute:

x=(x or 0)+1;    
y=math.log(x,3)  
print(y)os.exit()
Omar
quelle
1

PHP, 22 × 2 = 44 27 × 2 = 54

<?php $i++          ?>
<?php die(log($i,3))?>

Nur eine weitere Einstellung zu count-log3-out. Nicht sehr klein, aber mein erstes Golf;)

Lars Ebert
quelle
Bei PCG.SE, wie überall, überprüfen Sie bitte die Dokumentation vor dem Posten :).
Blackhole
@ Blackhole Guter Fang! Vielen Dank
Lars Ebert