分形大教堂


22

给定正整数n >= 1,输出n以下结构的第一行:

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

n第1索引的行是的二进制表示n,而不复制的最后一个字符的镜像,以#代替1和<space>到位0的所有行居中。

您必须以ASCII艺术形式输出,但是您可以使用任何非空白字符代替#示例中使用的字符。允许尾随空格,并允许尾随换行符。输出必须类似于示例,并且没有多余的前导空格或前导换行符。

您可以在此处查看分形大教堂的前1023行。

为了生成更大的测试用例,这是Python中的非引用参考实现


好主意。我不会猜到二进制数会产生如此漂亮的ascii艺术。
约拿(Jonah)

@Jonah谢谢:)很高兴您喜欢
HyperNeutrino

7
这两个链接都指向生成的大教堂。
奥塔维奥

@Otávio:我会解决,谢谢
HyperNeutrino

Answers:


6

玛特,10字节

:B2&Zv35*c

在线尝试!

说明

:      % 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
我想知道添加某种内建函数(对应于乘以35然后转换为char)是否会有所帮助。这似乎是经常使用
康纳尔奥布莱恩

@ ConorO'Brien经常使用,是的。但这将是内置两个字符的,所以不会有任何收益
Luis Mendo

没有收获?35*c是4个字符
Conor O'Brien

@ ConorO'Brien Ah,您是说35固定吗?这似乎有点具体。另一方面,某些挑战允许使用任何字符,因此这可能是一个好主意。您认为#最常见吗?
路易斯·门多

2
作为参考,已经实现了此功能(function Zc,带有character 35,即#)。谢谢@ ConorO'Brien!
路易斯·门多

5

05AB1E,9个字节

码:

Lb€û.c0ð:

使用05AB1E编码。在线尝试!

说明:

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个字节

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

在线尝试!

在Python 3中,s=f'{x+1:0{len(bin(n))-2}b}'.replace(*'0 ')它较短,但是int(input())print参数周围加括号会将其推入95个字节。


那是我的副本:)(但2**len(bin(n))/4无论如何都巧妙地使用了)
Outgolfer的Erik

3

JavaScript(ES6),106个字节

用途1作为非空白字符。

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

演示版

替代版本(相同大小)

没有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
非常好!第一次见过Math.clz32-我什至不知道它的存在!
伯乔拉修(Birjolaxew)'17年

@Birjolaxew是的,这是ES6的新增功能。偶尔会派上用场。
Arnauld

3

外壳21 20 18字节

感谢@Zgarb打高尔夫球2个字节!

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

在线尝试!

取消高尔夫/解释

为了避免冗长的填充,这确定了分形的宽度,该分形的宽度指定为,2*len(bin(N))-1并生成该长度的所有序列,并带有符号#,_(“ _”表示空格)。

由于笛卡尔幂是按顺序生成的,因此二进制数也是如此,所以这很好。在这一点上,我们需要做的所有事情就是过滤掉所有回文,基本上就是这样:

                    -- 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
Ṙ;可以是公正的R,并且ȯ是不必要的。不错的答案!
Zgarb

2

Mathematica,94个字节

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

2
我真的也必须去...
J42161217 '17

2

Mathematica,98个字节

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

Wolfram沙箱上尝试一下!在三个字节每个。

使用模式的分形特性,这是迄今为止与其他答案不同的方法。关键步骤是ArrayFlatten@{{0,#,0},{1,0,1},{1,#,1}}&,它做了分形的工作,最好以图片形式说明:

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

代码重复此步骤足够多次,以获取至少n行,然后修剪掉多余的行并很好地显示它。


2

盖亚 11字节

 #”B¦ₔṫ¦€|ṣ

在线尝试!

说明

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

谢谢TheLethalCoder的帮助。

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

在线尝试!

可以肯定的是,可以将其减少很多,很可能是在字符串的填充和反转中。


欢迎来到PPCG!目前,此答案只是一个代码段。可以通过x=>在字节数中添加来解决此问题,并注意不需要在结尾加上分号。Enumerable.Range(1,x).Select(z较短new int[x].Select((_,z)(我认为是正确的)。使用Linq时,应将其包括using System.Linq;在字节数中。您还在使用,Math因此您应该包括using System;或完全限定它。请注意,该时间会缩短为namespace System.Linq{}
TheLethalCoder

您不需要,' 'PadLeft通话中加入,因为默认情况下是空格。
TheLethalCoder


@TheLethalCoder给您带来的不便,我们已修复。
Dennis.Verweij

不用担心,我+1是一个不错的答案:)
TheLethalCoder

1

木炭,28字节

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

在线尝试!链接是详细版本的代码。说明:

A…·¹Nθ

创建第一个n自然数的列表。

W⌈θ«

重复直到所有元素都为零。

Eθ§ #κ

将列表中每个元素的最后一个二进制数字打印为a #

↓⸿

移至上一列。

AEθ÷κ²θ

将列表中的所有元素除以2。

»‖O

绘制左半部分后,将其反映出来。


当前版本的木炭具有MapAssignRight(IntDivide, 2, q);节省3个字节的功能。
尼尔

1

J,29个字节

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

在线尝试!

说明

  • i. 整数,直到n,输入
  • (#.^:_1) 转换为基数2
  • (],}.@|.)逐行("1做这部分),取二进制数(]即身份fn),并,用其反向符号()表示它(|.),其中反向符号被斩首(}.)。
  • ' #'{~1s和0s 转换为哈希和空格。

您可以使用#.inv代替#.^:_1
科纳·奥布莱恩

@ ConorO'Brien,谢谢,没有意识到这一点。
约拿(Jonah)

这不是一个人吗?对于n = 1,您什么都不打印。无论如何,您可以像这样进行一些更改以减少一些字节' #'{~(,|.@}:)"1@#:@:>:@i.(如果允许删除一个字节,则可以再删除4个字节)。基本上,请使用一个钩子,因为它在叉齿为左时就像叉子一样,]并使用#:AFAIK与相同的内置函数#.inv。编辑:我认为我的回答足够类似,可以作为评论,如果您认为它应该是自己的回答,请告诉我。
科尔

@科尔,谢谢!我稍后再更新。我以为我已经尝试过了#:,但没有成功,但是我必须记住错误,因为您说对了。
约拿(Jonah)

您可能已经尝试过@Jonah,2 #:它只会得到最右边的数字。Monadic #:函数就像#.inv(或#.&:_1)。这不同于dyadic #:,后者仅给出与左参数中有原子数一样多的数字。
科尔于2008年

1

质子,95字节

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

在线尝试!

有太多错误,没有太多括号...我需要修复解析器...



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

Run as pipe with -nR or try it online. Uses 1 as non-whitespace.


sorry to spoil it, but something is wrong here. output for $argn=1 and $argn=3 is not correct, and $argn is 0-based (specified was 1-based)
Felix Palmen

1
@FelixPalmen fixed. The incorrectness was caused by the wrong base. Thanks for noticing.
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("");}

Try it online!

This is a function f(n) called with the number of rows n, using an exclamation mark (!) as non-whitespace character.

Explanation:

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

Suggest --n&&o+p(n);o; instead of --n?o,p(n),o:o; and for(;c++<n;puts(""))p(b); instead of while(c++<n)p(b),puts("");
ceilingcat

0

JavaScript (Node.js), 156 149 bytes

-7 bytes by @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"}
`

Try it online!

Recursive function. Unfortunately JS does not support reversing a string, so 19 bytes are used on turning it into an array and back.


1
You can use [...b] instead of b.split(""); you can also use .join``.substr(1) instead of .join("").substr(1); finally, I think you can use s+1 instead of s+"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..$_

Try it online!

Using '1' instead of '#' because it saves a couple bytes.


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.