Codice Sierpinskified


47

Scrivi un blocco di testo rettangolare che, quando disposto in un tappeto Sierpinski , usando blocchi di spazi della stessa dimensione per le porzioni vuote, crea un programma che genera il numero di iterazione del tappeto.

Ad esempio, se il blocco di testo è

TXT
BLK

quindi eseguendo il programma

TXTTXTTXT
BLKBLKBLK
TXT   TXT
BLK   BLK
TXTTXTTXT
BLKBLKBLK

dovrebbe uscire 1perché la forma del programma rappresenta la prima iterazione del tappeto Sierpinski.

Allo stesso modo, correndo

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

dovrebbe produrre 2 perché questa è la forma della seconda iterazione del tappeto Sierpinski.

Esecuzione del blocco di testo così com'è

TXT
BLK

dovrebbe essere prodotto 0perché può essere considerato l'iterazione zeroth.

Questo dovrebbe funzionare per tutte le ulteriori iterazioni. (Almeno in teoria, supponendo che il computer abbia la memoria e tutto il resto.)

Dettagli

  • I programmi non possono leggere o accedere alle informazioni sul loro codice sorgente. Trattalo come una sfida rigorosa.
  • L'output passa a stdout o alternativa simile. Emette solo il numero e una nuova riga finale facoltativa. Non ci sono input.
  • Il blocco di testo può contenere caratteri che non sono considerati terminatori di riga . Il blocco di testo può contenere spazi.
  • Lo "spazio vuoto" nel tappeto deve consistere interamente di caratteri spaziali .
  • Puoi facoltativamente supporre che tutti i programmi abbiano una nuova riga finale.

Puoi utilizzare questo frammento di stack per generare un tappeto per un determinato blocco di testo in qualsiasi iterazione:

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

punteggio

La proposta il cui blocco di testo iniziale è il più piccolo per area (larghezza per altezza) è il vincitore. L' TXT\nBLKesempio è 3 per 2 per un punteggio di 6. (Fondamentalmente vince il codice più corto, quindi il tag code-golf.)

Tiebreaker va alla presentazione che utilizza il minor numero di caratteri distinti nel loro blocco di testo. Se ancora in parità, la risposta pubblicata per prima vince.

Risposte:


23

CJam, 9 byte

Penso che questo possa essere migliorato, ma per ora, lasciaci andare ...

];U):U8mL

Come funziona :

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

Provalo online qui


35

piet - 32 * 6 = 192

inserisci qui la descrizione dell'immagine

Ho riempito lo spazio vuoto con il motivo a scacchi. Penso che renda il Sierpinski un po 'più scattante.

Ecco la seconda iterazione: inserisci qui la descrizione dell'immagine

originale: 32 * 7

inserisci qui la descrizione dell'immagine


19

> <> , 11 * 2 = 22

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

Qui adottiamo un approccio diverso utilizzando la funzionalità di salto / teletrasporto di> <>.

Il programma esegue solo i blocchi nella riga superiore, eseguendo il 1 ° / 2 ° blocco, quindi il 3 ° / 4 ° blocco, 9 ° / 10 ° blocco, 27 ° / 28 ° blocco, ecc. (Salendo con potenze di 3). Poiché la riga superiore ha 3^nblocchi, solo i nblocchi vengono eseguiti prima che il programma torni all'inizio, produca la parte superiore dello stack e si arresti (a causa delle nistruzioni posizionate tramite p).

Il programma sfrutta la regola "Non c'è input.", Poiché il icomando spinge -1 nello stack se EOF è soddisfatto. Quindi per testarlo dovrai reindirizzare un file vuoto.


Presentazione precedente, 7 * 4 = 28

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

La prima riga spinge continuamente la lunghezza dello stack per ogni blocco e cambia la prima "virgoletta in una freccia giù vusando il pcomando put. Quando la prima riga è finita, lo stack sembra

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

(Nota che l'iniziale lviene usata due volte.)

Le ultime tre righe contano quindi quante volte dobbiamo dividere per 3 prima di premere 1 (poiché> <> non ha una funzione di registro). Lo zero inferiore viene utilizzato per tenere traccia del conteggio.


13

Perl, 26

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

Questo utilizza le serie armoniche per approssimare il logaritmo di base 3. Penso che funzioni, ma l'ho provato solo per piccoli numeri. Grazie all'ossifrage schizzinoso per l'idea di usare die.

Vecchia versione (34):

$n--or$n=3**$s++;
print$s-1if!$o++;

È molto pulito!
ossifrage schifoso

10

Perl, 30 (15 × 2)

Prima di tutto, affermerò che 10 iterazioni sono un limite ragionevole, non 2 32 . Dopo 10 iterazioni, un programma composto da N byte si sarà espanso in ( N × 3 20 ) byte (più interruzioni di riga), che supera i 3 gigabyte anche per N = 1. Un'architettura a 32 bit non sarebbe completamente in grado di gestire 11 iterazioni. (E ovviamente non ci sono abbastanza particelle nell'universo per 2 32 iterazioni).

Quindi ecco la mia soluzione:

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

Questo funziona incrementando la variabile $nnella prima riga e calcolando il suo logaritmo ad ogni passo. La seconda riga stampa la parte intera di questo logaritmo ed esce.

Un semplice logaritmo su base e (2.718 ..) è abbastanza vicino da dare risultati corretti per le prime 10 iterazioni.


2
Secondo il PO, dovrebbe teoricamente funzionare per tutte le iterazioni.
Nathan Merrill,

2
@NathanMerrill Bene, ok. Ma per rispettare le specifiche originali avrebbe dovuto lavorare anche in universi alternativi. La domanda è stata modificata da allora.
ossifrage schifoso

Ho cambiato la domanda a causa dei punti positivi qui esposti. Sono d'accordo sul fatto che l'utilizzo del registro naturale sia piuttosto un'area grigia, ma onestamente non sono troppo preoccupato poiché questo non sta vincendo.
Calvin's Hobbies,

La maggior parte di questi invii mantiene il controllo solo nella riga superiore di 3 ^ nx 1 tessere. Se si genera semplicemente quel segmento del tappeto, è possibile ridimensionare ulteriormente. Quasi sicuramente dove gli errori di arrotondamento ti spezzeranno.
captncraig,

1
Come ho già detto, la domanda originale richiedeva un codice che potesse ridimensionarsi a un numero "ragionevole" di iterazioni (fino a 2 ^ 32) . Se fai i conti, scoprirai che anche un singolo byte si espanderebbe a oltre 10 ^ 4098440370 byte dopo tante iterazioni. Ho proposto una risposta che pensavo fosse un po ' più ragionevole, ma da allora la parola "ragionevole" è scomparsa dalla domanda: - /. Guarda, ho finito qui. Basta votare questa risposta se non ti piace.
ossifrage schifoso

9

Golfscript, 9 * 2 = 18

0+       
,3base,(}

(Nota che la prima riga ha spazi finali per renderla rettangolare)

Non sono riuscito a trovare una funzione di registro per Golfscript, quindi ho basedovuto farlo.

Golfscript inizia con una stringa vuota, quindi 0+aumenta solo la lunghezza della stringa di 1 (per coerenza). Quando la prima riga sarà terminata, lo stack avrà una stringa di lunghezza 3^n, di cui prendiamo la base di registro 3 prima di commentare. nviene quindi stampato automaticamente.


È possibile salvare 2 caratteri utilizzando un numero intero anziché una stringa e quindi salvando ,la seconda riga. Prima riga 0or):; seconda riga 3base,(}. L'altro obiettivo ovvio è quello (sulla seconda riga. Questo è più complicato, ma può anche essere rimosso sostituendo la prima riga con 1+~abs(un rettangolo 7 * 2.
Peter Taylor,

8

C, 12x8 = 96

Ispirato da @ciamej, l'ho ridotto. Usa quella divisione per 3 prese, oltre alla consapevolezza che il tappeto converte efficacemente un if in un ciclo while.

Il codice è stato testato su gcc / Ubuntu per iterazioni fino a 3.

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

Soluzione precedente: C, 11x12

Non un vincitore di dimensioni, ma ehi, è C.

Trova log2 del blocco dei conteggi tramite bitshifting, quindi utilizza alcuni numeri magici e troncamento int per stimare log3. La matematica dovrebbe funzionare fino a 26 iterazioni (un numero di 42 bit).

#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//__

Ciao, ho pubblicato una versione abbreviata della tua soluzione.
ciamej,

Bel trucco con questo se! ;)
ciamej,

6

CJam, 9 byte

L'idea di utilizzare ]proviene da Optimizer, ma utilizza un metodo molto diverso per contare.

X~]:X,8mL

Provalo online

Come funziona:

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

Altre due soluzioni a 9 byte

]X+:X,8mL

],X+:X8mL

Questo in realtà lega Optimizer, anche con il tiebreaker. : P Tiebreakerbreaker: vittorie post precedenti.
Calvin's Hobbies,

Penso che sia una buona soluzione a prescindere. Non sono riuscito a battere 9 caratteri.
PhiNotPi,

Penso che l'approccio generale sia lo stesso (e che sia l'unico approccio sensato) - Avere una variabile, incrementarla di 1 in qualche modo.
Ottimizzatore,

4

Python 2, 15 * 3 = 45

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

Un'altra implementazione dell'idea count-first-row-then-log-three-and-exit. Probabilmente può ancora essere giocato un po 'di più.


2

bc, 2 * 16 + 1 = 33

Il +1 extra nel punteggio è dovuto -lall'opzione bc:

a+=1;          
l(a)/l(3);halt;

2

Golfscript, 7 * 2 = 14

1+~abs(
3base,}

Questo si ispira alla risposta di Sp3000 , e in particolare al desiderio di ottimizzare la lunga seconda linea. 3base,è breve quanto un logaritmo in base 3 otterrà in GS e il super-commento }è chiaramente ottimale.

Ciò che è necessario per la prima riga è mappare la stringa vuota ''dallo stdin iniziale su 0 e quindi mappare ogni intero non negativo al suo successore. In questo modo terminiamo la prima riga con 3^n - 1nello stack e 3base,non richiede alcun decremento.


2

C, 13x8

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

1

Perl, 76

So che probabilmente non ha molto senso pubblicare questo dato che è già stato completamente battuto, ma ecco comunque la mia soluzione attuale.

$_++;                                 
if(not$_&$_-1){print log()/log 8;$_--}

@Alex Non sembra funzionare, nemmeno alla prima iterazione.
PhiNotPi il

Sì, funziona così com'è. Hai testato il tuo metodo?
PhiNotPi,

Il mio funziona su ideone: ideone.com/othumP .
PhiNotPi il

Gotcha. Mi mancava un dettaglio importante che gli impediva di funzionare prima. Hai ragione, il mio suggerimento non è corretto.
Alex A.,

1

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

Una soluzione più semplice> <>:

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

Per prima cosa eseguiamo la riga superiore dei blocchi superiori. 'v'00pmette valla prima posizione dell'intero programma dirigendo il puntatore del programma verso il basso quando torna all'inizio dopo aver raggiunto la fine della riga. Prima di allora ogni blocco spinge 0 e la lunghezza della pila + 1 su di esso. (lo stack sarà 0 2 0 4 0 6 ...)

Nella prima metà del secondo e terzo contiamo quante volte possiamo dividere l'elemento in cima allo stack prima di ottenere 2 (lo memorizziamo nel secondo in alto).

Alla fine abbiamo generato il secondo elemento in cima alla pila.


1

Lua, 3 * 17 = 51

Stessa strategia della maggior parte delle persone:

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

1

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

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

Solo un'altra interpretazione di count-log3-out. Non molto piccolo, ma il mio primo golf;)


Su PCG.SE come in qualsiasi altro luogo, controlla la documentazione prima di pubblicare :).
Blackhole

@Blackhole Buona cattura! Grazie
Lars Ebert
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.