矩形假分形


13

目标

该程序的目标是绘制一个ASCII艺术矩形,该矩形的大小在水平方向和垂直方向上反复翻倍。每次矩形大小加倍时,多余的区域将用不同的字符表示,并且先前的区域将保持不变。最小的两个部分各包含一个字符,并且可以位于任何角落。

该程序接受单个整数作为输入,定义整个矩形包含的部分数量。

不允许其他外部资源或输入。

样本输入和输出

10

ABDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
CCDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ

选择标准

一周内最短的代码将赢得积分。


非4的幂的输出应该是什么?
marinus 2014年

是否要求输出的顺序为A,B,C等?
肯德尔·弗雷

2
@marinus 4的幂有什么特别之处?也许您误解了这个例子?
肯德尔·弗雷

@KendallFrey,不,仅需要n个唯一的可打印字符。
Hand-E-Food

难道一定要在左上角正是复发
mniip

Answers:


10

APL,25个字符/字节*

{⍉⍣⍵⊃{a,⍺⍴⍨⍴a←⍉⍪⍵}/⌽⍵↑⎕A}

分解图

{                   ⍵↑⎕A}   ⍝ take the first ⍵ letters
    ⊃{           }/⌽        ⍝ fold over them, using the first one as initial accum. value
            a←⍉⍪⍵           ⍝    ensure the accum. is a table, transpose it and call it 'a'
        ⍺⍴⍨⍴                ⍝    make a table as large as 'a' filled with the next letter
      a,                    ⍝    append it to the right of 'a' and loop as new accumulator
 ⍉⍣⍵                        ⍝ transpose the result as many times as the original ⍵ number

例子

      {⍉⍣⍵⊃{a,⍺⍴⍨⍴a←⍉⍪⍵}/⌽⍵↑⎕A}¨⍳8
A AB  AB  ABDD  ABDD  ABDDFFFF  ABDDFFFF  ABDDFFFFHHHHHHHH
      CC  CCDD  CCDD  CCDDFFFF  CCDDFFFF  CCDDFFFFHHHHHHHH
                EEEE  EEEEFFFF  EEEEFFFF  EEEEFFFFHHHHHHHH
                EEEE  EEEEFFFF  EEEEFFFF  EEEEFFFFHHHHHHHH
                                GGGGGGGG  GGGGGGGGHHHHHHHH
                                GGGGGGGG  GGGGGGGGHHHHHHHH
                                GGGGGGGG  GGGGGGGGHHHHHHHH
                                GGGGGGGG  GGGGGGGGHHHHHHHH

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
*:APL可以在它自己的(传统)被写入的单字节字符集即APL符号映射到上部128个字节值。因此,出于计分的目的,仅使用ASCII字符和APL符号的N个字符的程序可以认为是N个字节长。


9

GolfScript,30个字符

~(,[0`]{{[49+]1$,*+}+%zip}@/n*

示例(在线运行):

> 7
01335555
22335555
44445555
44445555
66666666
66666666
66666666
66666666

这会产生偶数的错误输出,例如问题中的那个……
Timwi 2014年

@Timwi我刚刚测试了它,它对我有用。输出已转置,但未在问题中指定方向。
2014年

好吧,我想我当时太严格了:)
Timwi 2014年

@Howard Hm,这就是我的理解“并且以前的区域保持不变”。他说前两个字符可能在任何角落,但他没有说方向可能会改变。
马丁·恩德

7

Python 2.7-85 103

这使用zip(*s)语法来连续转置列表。非常感谢Daniel削尖了12个字符的技巧!然后通过使用数字而不是字母来剃光一些。

s=[]
for i in range(input()):x=1<<i/2;s=zip(*s+[chr(65+i)*x]*x)
for i in s:print''.join(i)

同样,这是使用1<<x而不是2**x因为移位具有较低的(?)优先级。观察:

>>> 1<<(2*3)
64
>>> 1<<2*3
64
>>> 2**2*3
12
>>> 2**(2*3)
64

和一些输出:

10
01335555777777779999999999999999
22335555777777779999999999999999
44445555777777779999999999999999
44445555777777779999999999999999
66666666777777779999999999999999
66666666777777779999999999999999
66666666777777779999999999999999
66666666777777779999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999

1
真好 您可以使用将其缩短一点for i in s:print''.join(i)
丹尼尔·卢巴罗夫

5

Ruby,88岁

从标准输入读取N。

s=[?A]
66.upto(64+gets.to_i){|i|x=i.chr*y=s.size;i%2<1?s.map!{|r|r+x}:s+=[x*2]*y}
puts s

N = 8的示例用法:

echo 8 | rectangular-pseudo-fractal.rb

输出:

ABDDFFFFHHHHHHHH
CCDDFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH

N = 10

echo 10 | rectangular-pseudo-fractal.rb

输出:

ABDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
CCDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ

这个输出看起来像什么?

@LegoStormtroopr添加了一些示例,但是与问题的格式完全相同。
Paul Prestidge 2014年

4

J,57 43

(,`,.@.(=/@$@[)$${&a.@(66+2&^.@#@,)^:)1$'A'

例子:

5 (,`,.@.(=/@$@[)$${&a.@(66+2&^.@#@,)^:)1$'A'
ABDDFFFF
CCDDFFFF
EEEEFFFF
EEEEFFFF

7 (,`,.@.(=/@$@[)$${&a.@(66+2&^.@#@,)^:)1$'A'
ABDDFFFFHHHHHHHH
CCDDFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH

C和D都水平延伸。它们应水平和垂直交替。
Hand-E-Food

@ Hand-E-Food你是对的。感谢您指出了这一点。我已经固定了代码(并发布了)。
barbermot 2014年

4

MATLAB,86个字符

我在MATLAB中最短的尝试,由@flawr(两次!)拉皮条:

function M=f(n)
M='';
if n
M=cat(mod(n,2)+1,f(n-1),64+n*ones(2.^fix(n/2-[.5,1])));
end

输出示例:

>> disp(f(7))
ACEEGGGG
BCEEGGGG
DDEEGGGG
DDEEGGGG
FFFFGGGG
FFFFGGGG
FFFFGGGG
FFFFGGGG

这将为您节省一些字节:function M=f(n) M=''; if n M=cat(mod(n,2)+1,f(n-1),64+n*ones(2.^fix([n-1,n-2]/2))); end
更加模糊的

@flawr:哦!明显!
knedlsepp 2015年

通过替换的参数保存另一个字节fixfix(n/2-[.5,1])PS:跟真的很好的解决方案cat,不知道该用在这里你可以选择尺寸=)
flawr

@flawr:在我看来我很浪费。;-)
knedlsepp 2015年

我只是注意到您是这里的新手,所以欢迎访问codegolf.SE,我很高兴a。)还有一些matlab迷,b。)这里有说德语的人(我认为)!
瑕疵的

3

q [73个字符]

{"c"$64+{n:x 0;m:x 1;if[2>n;m:(),m];(o;$[n-2*n div 2;,';,][m;(#m;#m 0)#o:n+1])}/[x-1;(1;1)]1}

10
"ABDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ"
"CCDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ"
"EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ"
"EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ"
"GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ"
"GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ"
"GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ"
"GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ"
"IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ"
"IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ"
"IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ"
"IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ"
"IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ"
"IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ"
"IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ"
"IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ"

3
"AB"
"CC"

6
"ABDDFFFF"
"CCDDFFFF"
"EEEEFFFF"
"EEEEFFFF"

3

滑行,59个字符

❶塊갠分감⓶左貶終辦감標가⓺貶⓹開上❶❶貶雙是不⒉갠乘⒉終가①上뀀❷②갠分小是增終❸⓷另要감右⓶갠加⓶終丟字⓶終丟겠終

(如果我有以2为底的对数的说明,那么该程序可能会短很多,但我没有,所以我通过循环手动进行。)

带注释的代码

n 是输入。

❶ | n n

f = i => (1 << (i/2)) - 1;
塊갠分감⓶左貶終 | n n f

w = f(n);
辦 | n w f

d = 1;
감 | n w f d

s = "";
標 | n w f d M [s]

for (y in [0..f(n-1)])
가⓺貶⓹開上 | w d M [s] y

    if ((y & (y-1)) == 0) d *= 2;
    ❶❶貶雙是不⒉갠乘⒉終 | w d M [s] y

    for (x in [0..w])
    가①上 | w d M [s] y x

        c = 64; // '@'
        뀀 | w d M [s] y x c

        if (x < d/2) c++;
        ❷②갠分小是增終 | w d M [s] y x c

        a = x | y;
        ❸⓷另 | w d M [s] y c a

        while (a > 0) { a >>= 1; c += 2; }
        要감右⓶갠加⓶終丟 | w d M [s] y c

        s += (char) c;
        字⓶ | w d M [s] y
    終丟 | w d M [s]

    s += "\n"
    겠 | w d M [s]
終

输出量

对于n= 6:

ABDDFFFF
CCDDFFFF
EEEEFFFF
EEEEFFFF

当然,您可以将뀀@)更改为任何其他基本字符,例如,使用(space)和n= 7:

!"$$&&&&
##$$&&&&
%%%%&&&&
%%%%&&&&
''''''''
''''''''
''''''''
''''''''

不会使程序更长的最大数字是(= 255),这使我们(n这次= 8):

Āāăăąąąąćććććććć
ĂĂăăąąąąćććććććć
ĄĄĄĄąąąąćććććććć
ĄĄĄĄąąąąćććććććć
ĆĆĆĆĆĆĆĆćććććććć
ĆĆĆĆĆĆĆĆćććććććć
ĆĆĆĆĆĆĆĆćććććććć
ĆĆĆĆĆĆĆĆćććććććć

如果我们将程序长度增加1个字符,例如使用냟및(= \u4DFF)和n= 9,则得到:

一丁七七丅丅丅丅万万万万万万万万
丂丂七七丅丅丅丅万万万万万万万万
丄丄丄丄丅丅丅丅万万万万万万万万
丄丄丄丄丅丅丅丅万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈

3

C#,239个 185 182 180字节

C#在较冗长的语言上一无所有。

using C=System.Console;
class P{
    static void Main(string[]a){
        for(int x,i,n=int.Parse(a[0]);n-->0;C.CursorTop=0)
            for(i=1<<n,x=1<<n/2+n%2;i-->0;)
                C.Write((char)(n+33)+(i%x<1?"\n":""));
    }
}

输出,选择用于美化的字符:

!"$$&&&&((((((((****************
##$$&&&&((((((((****************
%%%%&&&&((((((((****************
%%%%&&&&((((((((****************
''''''''((((((((****************
''''''''((((((((****************
''''''''((((((((****************
''''''''((((((((****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************

1
不知道如何计算,但我计算了184。您可以通过从外for循环中去除括号来节省两个字符,使之为182。–
Bob

谢谢@鲍勃!在进行微优化时,我一定算错了。
Hand-E-Food

2

PERL,122个字符

$N=<>;$x=$r=1;do{$_=chr$a+++65;$s=$x;$o=$_ x$s;$o.=$_++x$s,$s*=2while$N+65>ord++$_;print"$o\n"x$r;$r=$x;$x*=2}while++$a<$N

加上空白:

$N=<>;
$x=$r=1;
do{
    $_=chr$a+++65;
    $s=$x;
    $o=$_ x$s;
    $o.=$_++x$s,$s*=2 
        while $N+65>ord++$_;
    print "$o\n"x$r;
    $r=$x;
    $x*=2
} while++$a<$N

输出:

$ echo 8 | perl pseudo-fractal.pl
ABDDFFFFHHHHHHHH
CCDDFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH

1

PERL, 94   81个字符

$N=$_;$_=$:=A;$h=1;++$i%2?s/$/$:x$h/gem:($_.=($/.$:x2x$h)x$h,$h*=2)while++$:,--$N

它逐个字母地迭代构造分形,添加新的行和列以及行和列...使用简单的字符串操作来做到这一点。请注意,我在滥用标准变量而不是字母1,以允许使用语法糖(例如省略空格$:x2等)。

加上空白和注释:

$N=$_;
$_=$:=A;                    # $: is current letter
$h=1;

++$i%2? 
s/$/$:x$h/gem:              # every odd run - add "columns"
($_.=($/.$:x2x$h)x$h,$h*=2) # every even run - add "rows"
while++$:,--$N              # iterate over letters

一些输出:

$ echo 8 | perl -p pseudo-fractal.fill.pl.5a5
ABDDFFFFHHHHHHHH
CCDDFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH

1

滑行,45个字符

가⓶貶上倘감雙⓶壹長⓸講增字⓶復⓷是標⓷各①合終并不⓶梴❸⓶疊合終不뀐標뀐并終終⓶丟各겠終

该解决方案的工作方式与其他Sclipting解决方案完全不同。它更无聊,但更短...

带注释

for i in [0..n-1]
가⓶貶上
    if (i != 0)
    倘
        i &= 1
        감雙
        e = list[0].Length
        ⓶壹長
        c = ((char) (c[0] + 1)).Repeat(e)
        ⓸講增字⓶復
        if (i)
        ⓷是
            concatenate c onto every element of list
            標⓷各①合終并
        else
        不
            concatenate c.Repeat(list.Length) onto list
            ⓶梴❸⓶疊合
        終
    else (i.e., i == 0)
    不
        c = "A"
        뀐
        list = ["A"]
        標뀐并
    終
終
concatenate "\n" to every element in list
⓶丟各겠終

1

德尔福348 || 缩进449

没有缩进

var inp,j,i,x: integer;s:string;L:TStringlist;begin L:=TStringList.Create;readln(s);inp:=StrToIntDef(s,4);if inp<4then inp:=4;s:='';l.Add('AB');for I:=2to inp-1do begin j:=Length(L[0]);if i mod 2=0then for x:=0to L.Count-1do L.Add(s.PadLeft(j,Chr(65+i)))else for x:=0to L.Count-1do L[x]:=L[x]+s.PadLeft(j,Chr(65+i));end;Write(L.GetText);readln;end.

带缩进

var
  inp,j,i,x: integer;
  s:string;
  L:TStringlist;
begin
  L:=TStringList.Create;
  readln(s);
  inp:=StrToIntDef(s,4);
  if inp<4then inp:=4;
  s:='';
  l.Add('AB');

  for I:=2to inp-1do
  begin
    j:=Length(L[0]);
    if i mod 2=0then
      for x:=0to L.Count-1do L.Add(s.PadLeft(j,Chr(65+i)))
    else
      for x:=0to L.Count-1do
        L[x]:=L[x]+s.PadLeft(j,Chr(65+i));
  end;
  Write(L.GetText);
  readln;
end.

1

CJam,30(23)个字节

CJam比这项挑战还年轻几个月,因此没有绿色复选标记的资格。

l~(Sa1${{_,I'!+*+}%z}fI\{z}*N*

在这里测试。

OP在注释中阐明,允许使用任何唯一的可打印字符集,因此我只是从头开始使用可打印的ASCII字符(在角落处有一个空格,!下一个等等)。

如果方向可能在偶数输入和奇数输入之间改变(我不认为,但这就是GolfScript提交所做的事情),那么我可以用25个字节来做到这一点:

S]l~({{_,I'!+*+}%z}fIN*

这个想法真的很简单:从一个包含空格的网格开始,然后N-1次转置它,并用下一个字符将所有行加倍。

对于长版,最后我还会再次换位N-1次,以确保方向一致。

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.