Cathédrale fractale

22

Étant donné un entier positif n >= 1, affichez les premières nlignes de la structure suivante:

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

La n-ième ligne indexée est la représentation binaire de n, mise en miroir sans copier le dernier caractère, avec #à la place de 1 et <space>à la place de 0. Toutes les lignes sont centrées.

Vous devez sortir en tant qu'art ASCII mais vous pouvez utiliser n'importe quel caractère non blanc à la place de celui que j'utilise #dans l'exemple. Les espaces de fin sont autorisés et les retours à la ligne de fin sont autorisés. La sortie doit ressembler à l'exemple, et pas d'espace blanc de tête supplémentaire ni de nouvelle ligne de tête.

Vous pouvez voir les 1023 premières rangées de la cathédrale fractale ici .

Pour générer des cas de test plus volumineux, voici une implémentation de référence non golfée en Python

HyperNeutrino
la source
Bonne idée. Je n'aurais pas deviné les nombres binaires pour avoir produit un si bel art ascii.
Jonah
@Jonah Merci :) Heureux que vous l'
aimiez
7
Les deux liens pointent vers la cathédrale générée.
Otávio
@ Otávio: Je vais réparer, merci
HyperNeutrino

Réponses:

6

MATL , 10 octets

:B2&Zv35*c

Essayez-le en ligne!

Explication

:      % 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
Luis Mendo
la source
1
Je me demande s'il serait utile d'ajouter une sorte de builtin qui correspond à la multiplication par 35 puis à la conversion en char. Il semble être utilisé souvent
Conor O'Brien
@ ConorO'Brien Il est souvent utilisé, oui. Mais ce serait un deux caractères intégré, donc il n'y aurait aucun gain
Luis Mendo
Aucun gain? 35*cest de 4 caractères
Conor O'Brien
@ ConorO'Brien Ah, tu veux dire avec 35fixe? Cela semble un peu précis. D'un autre côté, certains défis permettent à n'importe quel personnage, donc ce peut être une bonne idée. Pensez-vous que #c'est le plus courant?
Luis Mendo
2
Pour référence, cette fonctionnalité a été implémentée (fonction Zc, avec caractère 35, ie #). Merci, @ ConorO'Brien!
Luis Mendo
5

05AB1E , 9 octets

Code:

Lb€û.c0ð:

Utilise l' encodage 05AB1E . Essayez-le en ligne!

Explication:

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
Adnan
la source
4

Gelée , 12 octets

RBUz0ZUŒBo⁶Y

Essayez-le en ligne!

Leaky Nun
la source
1
Je dois aussi y aller, donc je lirai les commentaires à mon retour. N'hésitez pas à me sur-golfer.
Leaky Nun
+1 pour "n'hésitez pas à me surpasser" et pour la bonne réponse.
Magic Octopus Urn
3

Python 2 , 92 octets

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

Essayez-le en ligne!

En Python 3, s=f'{x+1:0{len(bin(n))-2}b}'.replace(*'0 ')est plus court, mais int(input())et les parenthèses autour de l' printargument le poussent jusqu'à 95 octets.

Lynn
la source
C'est une copie de la mienne :) (mais une utilisation intelligente de 2**len(bin(n))/4toute façon)
Erik the Outgolfer
3

JavaScript (ES6), 106 octets

Utilise 1comme caractère non blanc.

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

Démo

Version alternative (même taille)

Sans 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):''
Arnauld
la source
1
Très agréable! La première fois que j'ai vu Math.clz32- je ne savais même pas que ça existait!
Birjolaxew
@Birjolaxew Yup, il s'agit d'un ajout ES6. Il est pratique de temps en temps.
Arnauld
3

Coque , 21 20 18 octets

Merci @Zgarb d'avoir joué au golf sur 2 octets!

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

Essayez-le en ligne!

Non golfé / Explication

Pour éviter un long rembourrage, cela détermine la largeur de la fractale qui est donnée en tant que 2*len(bin(N))-1et génère toutes les séquences de cette longueur avec les symboles #,_(«_» désigne un espace).

Étant donné que la puissance cartésienne est générée dans l'ordre et que les nombres binaires le sont aussi, c'est très bien. Tout ce que nous devons faire pour obtenir la fractale à ce stade, c'est filtrer tous les palindromes et c'est essentiellement ça:

                    -- 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)
ბიმო
la source
1
Ṙ;peut être juste Ret ȯinutile. Belle idée de réponse!
Zgarb
2

Mathematica, 94 octets

Column[Row/@Table[s=IntegerDigits[i,2];Join[s,Reverse@Most@s]/.{0->" ",1->"#"},{i,#}],Center]&
J42161217
la source
2
Je dois vraiment y aller aussi ...
J42161217
2

Mathematica, 98 octets

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

Essayez-le dans le bac à sable Wolfram ! Le et sont trois octets chacun.

C'est une approche différente des autres réponses jusqu'à présent, en utilisant la nature fractale du motif. L'étape clé est ArrayFlatten@{{0,#,0},{1,0,1},{1,#,1}}&, qui fait le truc fractal, mieux expliqué sous forme d'image:

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

Le code répète cette étape suffisamment de fois pour obtenir au moins n lignes, puis supprime les lignes supplémentaires et l'affiche correctement.

Pas un arbre
la source
2

Gaia , 11 octets

 #”B¦ₔṫ¦€|ṣ

Essayez-le en ligne!

Explication

    ¦ₔ       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
Chat d'affaires
la source
2

Python 2 , 120 118 118 107 octets

merci @luismendo, @officialaimm, @ halvard-hummel

def f(l):
 for a in range(1,l+1):print(bin(a)[2:]+bin(a)[-2:1:-1]).replace(*'0 ').center(len(bin(l+1))*2-4)

Essayez-le en ligne!

wrymug
la source
2
replace(*'0 ')pour 2 octets
officialaimm
2
107 octets
Halvard Hummel
2

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

merci TheLethalCoder pour l'aide.

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

Essayez-le en ligne!

assez sûr que cela peut être réduit de beaucoup, très probablement dans le rembourrage et l'inversion de la chaîne.

Dennis.Verweij
la source
Bienvenue chez PPCG! Pour le moment, cette réponse n'est qu'un extrait de code. Il peut être corrigé en ajoutant le x=>dans le nombre d'octets et notez que vous n'avez pas besoin d'inclure le point-virgule de fin. Enumerable.Range(1,x).Select(zest plus court que new int[x].Select((_,z)(je pense que c'est correct). Lorsque vous utilisez Linq, vous devez inclure using System.Linq;votre nombre d'octets. Vous l'utilisez également Math, vous devez donc l'inclure using System;ou le qualifier entièrement. Notez que cela est alors plus court quenamespace System.Linq{}
TheLethalCoder
Vous n'avez pas besoin d'inclure ,' 'dans l' PadLeftappel car un espace est la valeur par défaut.
TheLethalCoder
@TheLethalCoder désolé pour le désagrément, il est maintenant corrigé.
Dennis.Verweij
Pas de soucis +1 de ma part, c'est une bonne réponse :)
TheLethalCoder
1

Fusain , 28 octets

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

A…·¹Nθ

Créez une liste des premiers nnombres naturels.

W⌈θ«

Répétez jusqu'à ce que tous les éléments soient nuls.

Eθ§ #κ

Imprime le dernier chiffre binaire de chaque élément de la liste sous la forme d'un ou #.

↓⸿

Passez à la colonne précédente.

AEθ÷κ²θ

Divisez tous les éléments de la liste par deux.

»‖O

Une fois la moitié gauche dessinée, réfléchissez-la.

Neil
la source
Les versions actuelles de Charcoal ont MapAssignRight(IntDivide, 2, q);ce qui économise 3 octets.
Neil
1

J, 29 octets

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

Essayez-le en ligne!

explication

  • i. entiers jusqu'à n, l'entrée
  • (#.^:_1) converti en base 2
  • (],}.@|.)ligne par ligne ( "1fait cette partie), prenez le nombre binaire ( ]est l'identité fn), et cat il ( ,) avec son inverse ( |.), où l'inverse est décapité ( }.).
  • ' #'{~convertit les 1s et 0s en hachages et espaces.
Jonas
la source
Vous pouvez utiliser à la #.invplace de #.^:_1.
Conor O'Brien
@ ConorO'Brien, merci, n'en était pas conscient.
Jonah
N'est-ce pas un coup? Car n = 1, vous n'imprimez rien. Quoi qu'il en soit, vous pouvez raser quelques octets avec quelques modifications comme cela ' #'{~(,|.@}:)"1@#:@:>:@i.(si vous êtes autorisé à être désactivé par un, vous pouvez supprimer 4 octets supplémentaires). Fondamentalement, utilisez un crochet car il fonctionne exactement comme une fourchette lorsque la dent gauche est ]et utilisez le intégré dans #:lequel AFAIK est à peu près le même #.inv. EDIT: Je pense que ma réponse est assez similaire pour justifier d'être un commentaire, faites-moi savoir si vous pensez que ce devrait être une réponse à part entière.
cole
@cole, merci! je vais le mettre à jour un peu plus tard. Je pensais avoir essayé #:et ça n'a pas fonctionné, mais je dois me souvenir mal parce que vous avez raison.
Jonah
@Jonah, vous avez peut-être essayé, 2 #:qui n'obtiendra que le chiffre le plus à droite. #:Fonctions monadiques comme #.inv(ou #.&:_1). Cela diffère de dyadique #:, qui donne seulement autant de chiffres qu'il y a d'atomes dans son argument de gauche.
cole
1

Proton , 95 octets

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

Essayez-le en ligne!

Il y a trop de bugs pour ne pas avoir trop de parenthèses ... J'ai besoin de corriger l'analyseur ...

HyperNeutrino
la source
1

PHP, 98 97 95 94 + 1 octets

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

Exécuter en tant que pipe avec -nRou l' essayer en ligne . Utilise 1comme espace non blanc.

Titus
la source
désolé de le gâcher, mais quelque chose ne va pas ici. sortie pour $argn=1et $argn=3n'est pas correcte, et $argnest basée sur 0 (spécifié était basé sur 1)
Felix Palmen
1
@FelixPalmen corrigé. L'inexactitude a été causée par une mauvaise base. Merci d'avoir remarqué.
Titus
0

Python 2 , 93 octets

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

Essayez-le en ligne!

Erik le Outgolfer
la source
0

C (gcc) , 146 108 105 octets

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

Essayez-le en ligne!

Il s'agit d'une fonction f(n)appelée avec le nombre de lignes n, utilisant un point d'exclamation ( !) comme caractère non blanc.

Explication :

#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]));
}
Felix Palmen
la source
Suggérer à la --n&&o+p(n);o;place de --n?o,p(n),o:o;et for(;c++<n;puts(""))p(b);au lieu dewhile(c++<n)p(b),puts("");
plafondcat
0

JavaScript (Node.js) , 156 149 octets

-7 octets par @ 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"}
`

Essayez-le en ligne!

Fonction récursive. Malheureusement, JS ne prend pas en charge l'inversion d'une chaîne, donc 19 octets sont utilisés pour la transformer en tableau et inversement.

Birjolaxew
la source
1
Vous pouvez utiliser à la [...b]place de b.split(""); vous pouvez également utiliser .join``.substr(1)au lieu de .join("").substr(1); enfin, je pense que vous pouvez utiliser à la s+1place des+"1"
Conor O'Brien
0

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

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

Essayez-le en ligne!

Utiliser '1' au lieu de '#' car cela économise quelques octets.

Xcali
la source