13
\$\begingroup\$

Goal

The program's goal is to draw an ASCII art rectangle repeatedly doubled in size, alternating horizontally and vertically. Each time the rectangle doubles in size, the extra area is represented by a different character and the previous areas remain unchanged. The two smallest sections contain one character each and may be in any corner.

The program accepts a single integer as input, defining the number of sections the full rectangle contains.

No other external resources or inputs are allowed.

Sample input and output

10

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

Selection criteria

The shortest code in a week wins the points.

\$\endgroup\$
8
  • \$\begingroup\$ What should the output be for non-powers of 4? \$\endgroup\$
    – marinus
    Jan 31, 2014 at 1:27
  • \$\begingroup\$ Is the output required to be of the sequence A, B, C, etc.? \$\endgroup\$ Jan 31, 2014 at 1:28
  • 2
    \$\begingroup\$ @marinus What is special about powers of 4? Maybe you misunderstood the example? \$\endgroup\$ Jan 31, 2014 at 1:28
  • \$\begingroup\$ @KendallFrey, no, there just needs to be n unique printable characters. \$\endgroup\$ Jan 31, 2014 at 2:48
  • \$\begingroup\$ Does it have to recur exactly in the top left corner \$\endgroup\$
    – mniip
    Jan 31, 2014 at 5:01

15 Answers 15

10
\$\begingroup\$

APL, 25 chars/bytes*

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

Exploded view

{                   ⍵↑⎕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

Examples

      {⍉⍣⍵⊃{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 can be written in its own (legacy) single-byte charset that maps APL symbols to the upper 128 byte values. Therefore, for the purpose of scoring, a program of N chars that only uses ASCII characters and APL symbols can be considered to be N bytes long.

\$\endgroup\$
9
\$\begingroup\$

GolfScript, 30 characters

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

Example (run online):

> 7
01335555
22335555
44445555
44445555
66666666
66666666
66666666
66666666
\$\endgroup\$
4
  • \$\begingroup\$ This produces the wrong output for even numbers, such as the one in the question... \$\endgroup\$
    – Timwi
    Feb 1, 2014 at 15:24
  • \$\begingroup\$ @Timwi I just tested it an it works for me. The output is transposed but orientation wasn't specified in the question. \$\endgroup\$
    – Howard
    Feb 2, 2014 at 11:28
  • \$\begingroup\$ Alright, I guess I was too strict then :) \$\endgroup\$
    – Timwi
    Feb 2, 2014 at 17:03
  • \$\begingroup\$ @Howard Hm, that's how I understand "and the previous areas remain unchanged". He says the first two characters may be in any corner, but he doesn't say the orientation may change. \$\endgroup\$ Jan 30, 2015 at 13:49
7
\$\begingroup\$

Python 2.7 - 85 103

This uses the zip(*s) syntax to continually transpose the list. Big thanks to Daniel for his tip that shaved 12 characters! Then shaved a few more by using numbers instead of letters.

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)

Also, this uses 1<<x rather than 2**x as bit shift has lower(?) precedence. Observe:

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

And some output:

10
01335555777777779999999999999999
22335555777777779999999999999999
44445555777777779999999999999999
44445555777777779999999999999999
66666666777777779999999999999999
66666666777777779999999999999999
66666666777777779999999999999999
66666666777777779999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
88888888888888889999999999999999
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Nice. You can shorten it a bit with for i in s:print''.join(i). \$\endgroup\$ Feb 2, 2014 at 9:03
5
\$\begingroup\$

Ruby, 88

Reads N from standard input.

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

Example Usage for N=8:

echo 8 | rectangular-pseudo-fractal.rb

Output:

ABDDFFFFHHHHHHHH
CCDDFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH

N=10

echo 10 | rectangular-pseudo-fractal.rb

Output:

ABDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
CCDDFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
EEEEFFFFHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
GGGGGGGGHHHHHHHHJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
IIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJ
\$\endgroup\$
2
  • \$\begingroup\$ What does the output of this look like? \$\endgroup\$
    – user8777
    Jan 31, 2014 at 3:38
  • \$\begingroup\$ @LegoStormtroopr added some examples, it's the exact same format as the question though. \$\endgroup\$ Jan 31, 2014 at 4:00
4
\$\begingroup\$

J, 57 43

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

Examples:

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

7 (,`,.@.(=/@$@[)$${&a.@(66+2&^.@#@,)^:)1$'A'
ABDDFFFFHHHHHHHH
CCDDFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
\$\endgroup\$
2
  • \$\begingroup\$ C and D both extend horizontally. They should alternate horizontally and vertically. \$\endgroup\$ Feb 1, 2014 at 11:46
  • \$\begingroup\$ @Hand-E-Food you're right. Thanks for pointing that out. I've fixed code (and post). \$\endgroup\$
    – barbermot
    Feb 1, 2014 at 13:08
4
\$\begingroup\$

MATLAB, 86 Characters

My shortest try in MATLAB, pimped by @flawr (twice!):

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

Example output:

>> disp(f(7))
ACEEGGGG
BCEEGGGG
DDEEGGGG
DDEEGGGG
FFFFGGGG
FFFFGGGG
FFFFGGGG
FFFFGGGG
\$\endgroup\$
7
  • \$\begingroup\$ This will save you some bytes: 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 \$\endgroup\$
    – flawr
    Jan 30, 2015 at 20:41
  • \$\begingroup\$ @flawr: Oh! Obviously! \$\endgroup\$
    – knedlsepp
    Jan 30, 2015 at 21:02
  • \$\begingroup\$ Save another byte by replacing the argument of fix with fix(n/2-[.5,1]) PS: Really nice solution with cat, did not know about this use where you can choose the dimension=) \$\endgroup\$
    – flawr
    Jan 30, 2015 at 21:05
  • \$\begingroup\$ @flawr: It seems to me I'm quite wasteful. ;-) \$\endgroup\$
    – knedlsepp
    Jan 30, 2015 at 21:06
  • \$\begingroup\$ I just noticed you're new here, so welcome on codegolf.SE, it's nice to have a.) some more matlab junkies, b.) german speakers here (I assume)! \$\endgroup\$
    – flawr
    Jan 30, 2015 at 21:36
3
\$\begingroup\$

q [73 chars]

{"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}

example

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"
\$\endgroup\$
3
\$\begingroup\$

Sclipting, 59 characters

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

(This program could be quite a bit shorter if I had instructions for base-2 logarithm, but I don’t, so I do it manually with a loop.)

Annotated code

n is the input.

❶ | 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]
終

Output

For n = 6:

ABDDFFFF
CCDDFFFF
EEEEFFFF
EEEEFFFF

Of course you can change 뀀 (@) to any other base character, e.g. with (space) and n = 7:

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

The highest number that doesn’t make the program longer is (= 255), which gives us (n = 8 this time):

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

If we make the program 1 character longer, e.g. use 냟및 (= \u4DFF) and n = 9, we get:

一丁七七丅丅丅丅万万万万万万万万
丂丂七七丅丅丅丅万万万万万万万万
丄丄丄丄丅丅丅丅万万万万万万万万
丄丄丄丄丅丅丅丅万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
\$\endgroup\$
3
\$\begingroup\$

C#, 239 185 182 180 bytes

C# has nothing on the less verbose languages.

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

Output, characters chosen for prettiness:

!"$$&&&&((((((((****************
##$$&&&&((((((((****************
%%%%&&&&((((((((****************
%%%%&&&&((((((((****************
''''''''((((((((****************
''''''''((((((((****************
''''''''((((((((****************
''''''''((((((((****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Not sure how you counted, but I counted 184. You can save two characters by ditching the braces from the outer for loop, making 182. \$\endgroup\$
    – Bob
    Jan 31, 2014 at 6:33
  • \$\begingroup\$ Thanks @Bob! I must have miscounted while micro-optimizing. \$\endgroup\$ Feb 1, 2014 at 11:44
2
\$\begingroup\$

PERL, 122 chars

$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

with added whitespace:

$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

Output:

$ echo 8 | perl pseudo-fractal.pl
ABDDFFFFHHHHHHHH
CCDDFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
EEEEFFFFHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
GGGGGGGGHHHHHHHH
\$\endgroup\$
1
\$\begingroup\$

PERL,  94   81 chars

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

It constructs the fractal iteratively letter by letter, adding new rows and columns and rows and columns... Uses simple string operations to do that. Note that I am abusing standard variable instead of letter one to allow for syntax sugar (like omitting spaces - $:x2 etc.)

With added whitespace and comments:

$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

Some output:

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

Sclipting, 45 characters

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

This solution works completely differently from the other Sclipting solution. It’s much more boring, but it’s shorter...

Annotated

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
⓶丟各겠終
\$\endgroup\$
1
\$\begingroup\$

Delphi 348 || 449 with indent

Without indent

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.

With indent

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.
\$\endgroup\$
1
\$\begingroup\$

CJam, 30 (23) bytes

CJam is a few months younger than this challenge so it's not eligible for the green checkmark.

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

Test it here.

The OP clarified in a comment that any set of unique printable characters is allowed, so I'm just taking the printable ASCII characters from the start (with a space in the corner, ! next and so on).

If the orientation may change between even and odd inputs (which I don't think, but that's what the GolfScript submission does), I can do it in 25 bytes:

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

The idea is really simple: start with a grid containing a space, and then N-1 times transpose it and double all lines with the next character.

For the long version, at the end I also transpose again N-1 times in order to guarantee a consistent orientation.

\$\endgroup\$
0
\$\begingroup\$

Canvas, 22 bytes

A;╷{┐⤢l;L┘¹Zj@┘┘*+}╶[⤢

Try it here!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.