Cattedrale frattale


22

Dato un numero intero positivo n >= 1, genera le prime nrighe della seguente struttura:

   #
  # #
  ###
 #   #
 # # #
 ## ##
 #####
#     #
#  #  #
# # # #
# ### #
##   ##
## # ##
### ###
#######

L' nennesima riga indicizzata è la rappresentazione binaria di n, speculare senza copiare l'ultimo carattere, con #al posto di 1 e <space>al posto di 0. Tutte le righe sono centrate.

È necessario eseguire l'output come ASCII-art ma è possibile utilizzare qualsiasi carattere non bianco al posto di quello che uso #nell'esempio. Lo spazio bianco finale è consentito e è consentita una nuova riga finale. L'output deve assomigliare all'esempio e nessun ulteriore spazio bianco iniziale o nuova riga iniziale.

È possibile visualizzare le prime 1023 righe della cattedrale frattale qui .

Per generare casi di test più grandi, ecco un'implementazione di riferimento non modificata in Python


Bella idea Non avrei indovinato i numeri binari per aver prodotto un'arte ASCII così carina.
Giona,

@Jonah Grazie :) Lieto che ti piaccia
HyperNeutrino il

7
Entrambi i collegamenti indicano la cattedrale generata.
Otávio,

Risposte:


6

MATL , 10 byte

:B2&Zv35*c

Provalo online!

Spiegazione

:      % Implicitly input n. Push range [1 2 ... n]
B      % Convert to binary. Gives a matrix where each row corresponds to
       % a number. Rows have left-padding zeros if needed
2      % Push 2
&Zv    % Symmetrize along sepecified dimension (2nd means horizontally),
       % without repeating the last element
35*    % Multiply by 35 (ASCII code for '#')
c      % Convert to char. Char 0 is shown as space. Implicitly display

1
Mi chiedo se sarebbe utile aggiungere una sorta di builtin che corrisponde alla moltiplicazione per 35 e alla conversione in char. Sembra essere usato spesso
Conor O'Brien il

@ ConorO'Brien È usato spesso, sì. Ma sarebbe un built-in a due caratteri, quindi non ci sarebbe alcun guadagno
Luis Mendo

Nessun guadagno? 35*cè
composto da

@ ConorO'Brien Ah, intendi con 35fixed? Sembra un po 'specifico. D'altra parte, alcune sfide consentono qualsiasi carattere, quindi potrebbe essere una buona idea. Pensi che #sia il più comune?
Luis Mendo,

2
Per riferimento, questa funzione è stata implementata (funzione Zc, con carattere 35, cioè #). Grazie, ConorO'Brien!
Luis Mendo,

5

05AB1E , 9 byte

Codice:

Lb€û.c0ð:

Utilizza la codifica 05AB1E . Provalo online!

Spiegazione:

L              # List [1, .., input]
 b             # Convert each to binary
  €û           # Palindromize each binary number
    .c         # Join the array by newlines and centralize
      0ð:      # Replace zeroes by spaces


3

Python 2 , 92 byte

n=input()
for x in range(n):s=bin(2**len(bin(n))/4+x+1)[3:].replace(*'0 ');print s+s[-2::-1]

Provalo online!

In Python 3, s=f'{x+1:0{len(bin(n))-2}b}'.replace(*'0 ')è più breve, ma int(input())e le parentesi attorno printall'argomento lo spingono fino a 95 byte.


Questa è una mia copia :) (ma uso intelligente 2**len(bin(n))/4comunque)
Erik the Outgolfer

3

JavaScript (ES6), 106 byte

Utilizza 1come carattere non bianco.

f=(n,k=0)=>k++<n?[...Array(32-Math.clz32(n))].reduce((s,_,i)=>(c=k>>i&1||' ')+s+(i?c:''),'')+`
`+f(n,k):''

dimostrazione

Versione alternativa (stessa dimensione)

Senza Math.clz32():

f=(n,a=[k=i=0])=>n>>i+1?f(n,a,a[++i]=i):k++<n?a.reduce((s,i)=>(c=k>>i&1||' ')+s+(i?c:''),'')+`
`+f(n,a):''

1
Molto bella! La prima volta che ho visto Math.clz32, non sapevo nemmeno che esistesse!
Birjolaxew,

@Birjolaxew Sì, questa è un'aggiunta ES6. È utile ogni tanto.
Arnauld,

3

Buccia , 21 20 18 byte

Grazie @Zgarb per il golf off 2 byte!

S↑(tfS=↔ΠR" #"←DLḋ

Provalo online!

Ungolfed / Spiegazione

Per evitare una lunga imbottitura, questo determina la larghezza del frattale che viene dato come 2*len(bin(N))-1e genera tutte le sequenze di quella lunghezza con i simboli #,_('_' indica uno spazio).

Dal momento che il potere cartesiano viene generato in ordine e anche i numeri binari, va bene. Tutto ciò che dobbiamo fare per ottenere il frattale a questo punto, è filtrare tutti i palindromi e questo è tutto:

                    -- implicit input N
S↑(                 -- take N from the following list
        ΠR" #"      --   Cartesian power of [" #"] to
                Lḋ  --     number of bits in bin(N)
               D    --     2*
              ←     --     -1
    fS=↔            --   filter out palindromes
   t                --   drop the first line (all spaces)

1
Ṙ;può essere giusto Red ȯè superfluo. Bella idea di risposta!
Zgarb,

2

Mathematica, 94 byte

Column[Row/@Table[s=IntegerDigits[i,2];Join[s,Reverse@Most@s]/.{0->" ",1->"#"},{i,#}],Center]&

2
Devo davvero andare anch'io ...
J42161217

2

Mathematica, 98 byte

Riffle[Nest[ArrayFlatten@{{0,#,0},{1,0,1},{1,#,1}}&,{1},⌊Log2@#⌋]~Take~#"#"/. 0->" ","
"]<>""&

Provalo nella sandbox Wolfram ! I e sono tre byte ciascuno.

Finora è un approccio diverso dalle altre risposte, usando la natura frattale del modello. Il passaggio chiave è ArrayFlatten@{{0,#,0},{1,0,1},{1,#,1}}&, che fa le cose frattalmente, meglio spiegato in forma di immagine:

                 [    ]
                 [grid]
[    ]           [    ]
[grid]   --->   #      #
[    ]          #[    ]#
                #[grid]#
                #[    ]#

Il codice ripete questo passaggio abbastanza volte per ottenere almeno n righe, quindi taglia le righe aggiuntive e lo visualizza in modo corretto.


2

Gaia , 11 byte

 #”B¦ₔṫ¦€|ṣ

Provalo online!

Spiegazione

    ¦ₔ       For each number 1..input:
 #”B          Convert it to base 2 and use space as 0 and # as 1
      ṫ¦     Palindromize each
        €|   Centre the lines
          ṣ  Join with newlines


2

C # (.NET Core) , 192 178 byte 168 + 23

grazie TheLethalCoder per l'aiuto.

x=>new int[x].Select((_,z)=>Convert.ToString(z+1,2).PadLeft((int)Math.Log(x,2)+2).Replace('0',' ')).Aggregate((y,z)=>y+"\n"+z+new string(z.Reverse().Skip(1).ToArray()))

Provalo online!

abbastanza sicuro che questo può essere ridotto di molto, molto probabilmente nell'imbottitura e nell'inversione della corda.


Benvenuti in PPCG! Al momento questa risposta è solo uno snippet di codice. Può essere risolto aggiungendo il x=>conteggio dei byte e nota che non è necessario includere i punti e virgola finali. Enumerable.Range(1,x).Select(zè più breve come new int[x].Select((_,z)(penso che sia corretto). Mentre stai usando Linq, dovresti includerlo using System.Linq;nel conteggio dei byte. Stai anche utilizzando, Mathquindi dovresti includerlo using System;o qualificarlo completamente. Si noti che questo è più breve comenamespace System.Linq{}
TheLethalCoder

Non è necessario includere ,' 'nella PadLeftchiamata poiché uno spazio è l'impostazione predefinita.
TheLethalCoder


@TheLethalCoder mi dispiace per l'inconveniente, ora è stato risolto.
Dennis.Verweij,

Nessun problema +1 da me è una bella risposta :)
TheLethalCoder

1

Carbone , 28 byte

A…·¹NθW⌈θ«Eθ§ #κ↓⸿AEθ÷κ²θ»‖O

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

A…·¹Nθ

Crea un elenco dei primi nnumeri naturali.

W⌈θ«

Ripeti fino a quando tutti gli elementi sono zero.

Eθ§ #κ

Stampa l'ultima cifra binaria di ciascun elemento dell'elenco come o #.

↓⸿

Passa alla colonna precedente.

AEθ÷κ²θ

Dividi tutti gli elementi dell'elenco per due.

»‖O

Una volta che la metà sinistra è stata disegnata, riflettila.


Le versioni attuali di Charcoal hanno un MapAssignRight(IntDivide, 2, q);risparmio di 3 byte.
Neil,

1

J, 29 byte

' #'{~(],}.@|.)"1@(#.^:_1)@i.

Provalo online!

spiegazione

  • i. numeri interi fino a n, l'input
  • (#.^:_1) convertito in base 2
  • (],}.@|.)riga per riga ( "1fa quella parte), prendi il numero binario ( ]è l'identità fn) e lo cat ( ,) con il suo retro ( |.), dove viene decapitato il retro ( }.).
  • ' #'{~converte la 1s e la 0s in hash e spazi.

Puoi usare #.invinvece di #.^:_1.
Conor O'Brien,

@ ConorO'Brien, grazie, non ne ero a conoscenza.
Giona,

Questo non è spento da uno? Perché n = 1non stampi nulla. Ad ogni modo, puoi radere alcuni byte con alcune modifiche in questo modo ' #'{~(,|.@}:)"1@#:@:>:@i.(se ti è permesso di essere spento da uno puoi rimuovere altri 4 byte). Fondamentalmente, usa un gancio perché si comporta proprio come una forcella quando il dente sinistro è ]e usa il built-in in #:cui AFAIK è quasi uguale a #.inv. EDIT: immagino che la mia risposta sia abbastanza simile da giustificare un commento, fammi sapere se pensi che dovrebbe essere una risposta a sé stante.
Cole

@cole, grazie! lo aggiornerò un po 'più tardi. pensavo di aver provato #:e non ha funzionato, ma devo ricordare che è sbagliato perché hai ragione.
Giona,

@Jonah potresti aver provato 2 #:che otterrà solo la cifra più a destra. Le #:funzioni monadiche sono come #.inv(o #.&:_1). Ciò differisce dal diadico #:, che fornisce solo tante cifre quanti sono gli atomi nel suo argomento di sinistra.
Cole

1

Proton , 95 byte

r=>{for i:range(1,r)print(((bin(i)[2to]).rjust(len(bin(r))-2)[to-1,to by-1]).replace('0',' '))}

Provalo online!

Ci sono troppi bug per non avere troppe parentesi ... Devo sistemare il parser ...



1

PHP, 98 97 95 94 + 1 byte

while($r++<$argn)echo$s=strtr(sprintf("%".-~log($argn,2).b,$r),0," "),substr(strrev("
$s"),1);

Esegui come pipe -nRo provalo online . Utilizza 1come spazio non bianco.


mi dispiace rovinarlo, ma qualcosa non va qui. l'output per $argn=1e $argn=3non è corretto ed $argnè basato su 0 (specificato era basato su 1)
Felix Palmen

1
@FelixPalmen risolto. L'erroneità è stata causata dalla base sbagliata. Grazie per averlo notato.
Tito




0

C (gcc) , 146 108 105 byte

#define o putchar(33-!(c&(1<<n)))
b;c;p(n){--n?o,p(n),o:o;}f(n){while(n>>++b);while(c++<n)p(b),puts("");}

Provalo online!

Questa è una funzione f(n)chiamata con il numero di righe n, usando un punto esclamativo ( !) come carattere non di spazi bianchi.

Spiegazione :

#define o putchar(33-!(c&(1<<n)))
b;c;
p(n)
{
    // least significant bit not yet reached?
    --n?
            // print bit twice with recursive step between
            o,
            p(n),
            o
        // for least significant, just print this bit
        :o;
}

// the main "cathedral function":
f(r)
{
    // determine max number of bits to shift
    while(r>>++b);

    // iterate over rows
    while(c++<r)

        // print row recursively
        p(b),

        // newline
        puts("");
}

/**
 * footer, just calling the function
 */
main(int argc, char **argv)
{
    f(atoi(argv[1]));
}

Suggerisci --n&&o+p(n);o;invece --n?o,p(n),o:o;e for(;c++<n;puts(""))p(b);invece diwhile(c++<n)p(b),puts("");
ceilingcat il

0

JavaScript (Node.js) , 156 149 byte

-7 byte di @ ConorO'Brien

f=(n,w=n.toString(2).length,b=n.toString(2).replace(/0/g," "),s=" ".repeat(w-b.length))=>`${--n?f(n,w)+s+b+[...b].reverse().join``.substr(1):s+"1"}
`

Provalo online!

Funzione ricorsiva. Sfortunatamente JS non supporta l'inversione di una stringa, quindi vengono utilizzati 19 byte per trasformarla in un array e viceversa.


1
Puoi usare [...b]invece di b.split(""); puoi anche usare al .join``.substr(1)posto di .join("").substr(1); infine, penso che tu possa usare s+1invece dis+"1"
Conor O'Brien il

0

Perl 5 , 77 + 1 (-n) = 78 byte

$x=1+(log$_)/log 2;map{$_=sprintf"%0${x}b",$_;y/0/ /;say$_.chop.reverse}1..$_

Provalo online!

Usando '1' invece di '#' perché salva un paio di byte.


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.