Fraktale Kathedrale


22

Geben Sie bei einer positiven Ganzzahl n >= 1die ersten nZeilen der folgenden Struktur aus:

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

Die n-te 1-indizierte Zeile ist die binäre Darstellung von n, gespiegelt ohne Kopieren des letzten Zeichens, mit #anstelle von 1 und <space>anstelle von 0. Alle Zeilen sind zentriert.

Sie müssen als ASCII-Kunst ausgeben, können jedoch ein beliebiges Nicht-Leerzeichen anstelle dessen verwenden, was ich #im Beispiel verwende. Ein nachgestelltes Leerzeichen und ein nachgestelltes Zeilenumbruchzeichen sind zulässig. Die Ausgabe muss wie im Beispiel aussehen und darf keine zusätzlichen führenden Leerzeichen oder führenden Zeilenumbrüche enthalten.

Sie können die ersten 1023 Reihen der fraktalen Kathedrale hier anzeigen .

Um größere Testfälle zu generieren, finden Sie hier eine Referenzimplementierung in Python


Gute Idee. Ich hätte nicht gedacht, dass Binärzahlen so schöne ASCII-Kunst hervorbringen.
Jonah

@ Jonah Danke :) Schön, dass es dir gefällt
HyperNeutrino

7
Beide Links verweisen auf die generierte Kathedrale.
Otávio

@ Otávio: Ich werde reparieren, danke
HyperNeutrino

Antworten:


6

MATL , 10 Bytes

:B2&Zv35*c

Probieren Sie es online!

Erläuterung

:      % 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
Ich frage mich, ob es hilfreich wäre, eine Art eingebautes Element hinzuzufügen, das dem Multiplizieren mit 35 entspricht, und dann in char umzuwandeln. Es scheint oft verwendet zu werden
Conor O'Brien

@ ConorO'Brien Wird ja oft benutzt. Aber es wäre ein Zwei-Zeichen-eingebaut, so dass es keinen Gewinn geben würde
Luis Mendo

Kein Gewinn? 35*cist 4 Zeichen
Conor O'Brien

@ConorO'Brien Ah, meinst du mit 35Festnetz? Das scheint ein bisschen spezifisch zu sein. Auf der anderen Seite erlauben einige Herausforderungen jedes Zeichen, so dass es eine gute Idee sein kann. Denken Sie, dass dies #am häufigsten vorkommt?
Luis Mendo

2
Zu Referenzzwecken wurde diese Funktion implementiert (Funktion Zcmit Zeichen 35, dh #). Vielen Dank, @ ConorO'Brien!
Luis Mendo

5

05AB1E , 9 Bytes

Code:

Lb€û.c0ð:

Verwendet die 05AB1E- Codierung. Probieren Sie es online!

Erläuterung:

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 Bytes

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

Probieren Sie es online!

In Python 3 s=f'{x+1:0{len(bin(n))-2}b}'.replace(*'0 ')ist es kürzer, aber int(input())und Parens um das printArgument schieben es auf 95 Bytes.


Das ist eine Kopie von mir :) (aber geschickte Verwendung von 2**len(bin(n))/4sowieso)
Erik der Outgolfer

3

JavaScript (ES6), 106 Byte

Verwendet 1als Nicht-Leerzeichen.

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

Demo

Alternative Version (gleiche Größe)

Ohne 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
Sehr schön! Zum ersten Mal habe ich gesehen Math.clz32- ich wusste nicht einmal, dass es existiert!
Birjolaxew

@ Birjolaxew Yup, das ist ein ES6-Zusatz. Ab und zu ist es praktisch.
Arnauld

3

Schale , 21 20 18 Bytes

Vielen Dank an @Zgarb für das Golfen mit 2 Bytes!

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

Probieren Sie es online!

Ungolfed / Erklärung

Um langwieriges Auffüllen zu vermeiden, wird die Breite des Fraktals bestimmt, das als gegeben ist, 2*len(bin(N))-1und alle Folgen dieser Länge mit den Symbolen erzeugt #,_('_' bezeichnet ein Leerzeichen).

Da die kartesische Potenz in der richtigen Reihenfolge erzeugt wird und auch die Binärzahlen sind, ist dies in Ordnung. Alles, was wir tun müssen, um das Fraktal zu diesem Zeitpunkt zu erhalten, ist, alle Palindrome herauszufiltern, und das ist im Grunde genommen alles:

                    -- 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
Ṙ;kann gerecht sein Rund ȯist unnötig. Schöne Antwortidee!
Zgarb

2

Mathematica, 94 Bytes

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

2
Ich muss auch wirklich gehen ...
J42161217

2

Mathematica, 98 Bytes

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

Probieren Sie es am Wolfram Sandkasten ! Das und sind jeweils drei Bytes.

Es ist ein anderer Ansatz als die bisherigen Antworten, wobei die fraktale Natur des Musters verwendet wird. Der Schlüsselschritt ist ArrayFlatten@{{0,#,0},{1,0,1},{1,#,1}}&, was das Fraktale angeht, am besten in Bildform zu erklären:

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

Der Code wiederholt diesen Schritt so oft, bis er mindestens n Zeilen enthält, schneidet dann die zusätzlichen Zeilen ab und zeigt sie gut an.


2

Gaia , 11 Bytes

 #”B¦ₔṫ¦€|ṣ

Probieren Sie es online!

Erläuterung

    ¦ₔ       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 Bytes 168 + 23

danke TheLethalCoder für die Hilfe.

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

Probieren Sie es online!

ziemlich sicher, dass dies um ein Vielfaches reduziert werden kann, am wahrscheinlichsten beim Auffüllen und Umkehren der Saite.


Willkommen bei PPCG! Im Moment ist diese Antwort nur ein Codeausschnitt. Sie können dies beheben, indem Sie das x=>in die Byteanzahl einfügen und beachten, dass Sie das nachgestellte Semikolon nicht einschließen müssen. Enumerable.Range(1,x).Select(zist kürzer als new int[x].Select((_,z)(ich denke das ist richtig). Bei der Verwendung von Linq sollten using System.Linq;Sie die Anzahl der Bytes berücksichtigen. Sie verwenden es auch, Mathum es einzuschließen using System;oder vollständig zu qualifizieren. Beachten Sie, dass dies dann kürzer ist alsnamespace System.Linq{}
TheLethalCoder

Sie müssen keine Leerzeichen ,' 'in den PadLeftAufruf einfügen, da dies die Standardeinstellung ist.
TheLethalCoder


@TheLethalCoder sorry für die unannehmlichkeiten, es ist jetzt behoben.
Dennis.Verweij

Keine Sorge, +1 von mir, es ist eine schöne Antwort :)
TheLethalCoder

1

Kohle , 28 Bytes

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

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Erläuterung:

A…·¹Nθ

Erstellen Sie eine Liste der ersten nnatürlichen Zahlen.

W⌈θ«

Wiederholen, bis alle Elemente Null sind.

Eθ§ #κ

Gibt die letzte Binärziffer jedes Elements der Liste als oder aus #.

↓⸿

Zur vorherigen Spalte wechseln.

AEθ÷κ²θ

Teilen Sie alle Elemente der Liste durch zwei.

»‖O

Sobald die linke Hälfte gezeichnet wurde, reflektiere sie.


Aktuelle Versionen von Charcoal haben MapAssignRight(IntDivide, 2, q);3 Bytes gespart.
Neil

1

J, 29 Bytes

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

Probieren Sie es online!

Erläuterung

  • i. Ganzzahlen bis n, die Eingabe
  • (#.^:_1) konvertiert zu Basis 2
  • (],}.@|.)reihenweise ( "1erledigt diesen Teil), nimm die Binärzahl ( ]ist die Identität fn) und katze sie ( ,) mit ihrer Umkehrung ( |.), wobei die Umkehrung enthauptet wird ( }.).
  • ' #'{~konvertiert das 1s und 0s in Hashes und Leerzeichen.

Sie können #.invanstelle von verwenden #.^:_1.
Conor O'Brien

@ ConorO'Brien, danke, war sich dessen nicht bewusst.
Jonah

Ist das nicht aus um eins? Denn n = 1Sie drucken nichts. Wie auch immer, Sie können ein paar Bytes mit ein paar Änderungen abschneiden ' #'{~(,|.@}:)"1@#:@:>:@i.(wenn Sie um eins abschneiden dürfen, können Sie 4 weitere Bytes entfernen). Verwenden Sie im Grunde genommen einen Haken, da er sich wie eine Gabel verhält, wenn sich der linke Zinken befindet, ]und verwenden Sie das eingebaute, mit #:dem AFAIK in etwa identisch ist #.inv. EDIT: Ich denke, meine Antwort ist ähnlich genug, um einen Kommentar zu rechtfertigen. Lassen Sie es mich wissen, wenn Sie der Meinung sind, dass es eine eigene Antwort sein sollte.
Cole

@cole, danke! Ich werde es etwas später aktualisieren. Ich dachte, ich hätte es versucht #:und es hat nicht funktioniert, aber ich muss mich an etwas Falsches erinnern, weil du recht hast, dass es funktioniert.
Jonah

@Jonah du hast es vielleicht versucht, 2 #:was nur die am weitesten rechts stehende Ziffer ergibt . Monadic #:funktioniert genauso wie #.inv(oder #.&:_1). Dies unterscheidet sich von dyadisch #:, bei dem nur so viele Ziffern angegeben werden, wie Atome im linken Argument enthalten sind.
Cole

1

Proton , 95 Bytes

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

Probieren Sie es online!

Es gibt zu viele Fehler, um nicht zu viele Klammern zu haben ... Ich muss den Parser reparieren ...



1

PHP, 98 97 95 94 + 1 Bytes

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

Laufen Sie als Pipe mit -nRoder versuchen Sie es online . Verwendet 1als Nicht-Leerzeichen.


Entschuldigung, aber hier stimmt etwas nicht. Ausgabe für $argn=1und $argn=3ist nicht korrekt und $argnist 0-basiert (angegeben wurde 1-basiert)
Felix Palmen

1
@FelixPalmen behoben. Die Unrichtigkeit wurde durch die falsche Basis verursacht. Danke fürs bemerken.
Titus




0

C (GCC) , 146 108 105 Bytes

#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("");}

Probieren Sie es online!

Dies ist eine Funktion, f(n)die mit der Anzahl der Zeilen aufgerufen wird n, wobei ein Ausrufezeichen ( !) als Nicht-Leerzeichen verwendet wird.

Erklärung :

#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]));
}

Schlagen --n&&o+p(n);o;statt --n?o,p(n),o:o;und for(;c++<n;puts(""))p(b);stattwhile(c++<n)p(b),puts("");
Ceilingcat

0

JavaScript (Node.js) , 156 bis 149 Byte

-7 Bytes von @ 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"}
`

Probieren Sie es online!

Rekursive Funktion. Leider unterstützt JS das Umkehren eines Strings nicht, so dass 19 Bytes verwendet werden, um ihn in ein Array und zurück zu verwandeln.


1
Sie können [...b]anstelle von verwenden b.split(""); Sie können auch .join``.substr(1)anstelle von verwenden .join("").substr(1); Schließlich denke ich, Sie können s+1anstelle vons+"1"
Conor O'Brien

0

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

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

Probieren Sie es online!

Verwenden Sie '1' anstelle von '#', da dadurch ein paar Bytes gespart werden.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.