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.
-
\$\begingroup\$ What should the output be for non-powers of 4? \$\endgroup\$marinus– marinus2014年01月31日 01:27:24 +00:00Commented Jan 31, 2014 at 1:27
-
\$\begingroup\$ Is the output required to be of the sequence A, B, C, etc.? \$\endgroup\$Kendall Frey– Kendall Frey2014年01月31日 01:28:04 +00:00Commented Jan 31, 2014 at 1:28
-
2\$\begingroup\$ @marinus What is special about powers of 4? Maybe you misunderstood the example? \$\endgroup\$Kendall Frey– Kendall Frey2014年01月31日 01:28:57 +00:00Commented Jan 31, 2014 at 1:28
-
\$\begingroup\$ @KendallFrey, no, there just needs to be n unique printable characters. \$\endgroup\$Hand-E-Food– Hand-E-Food2014年01月31日 02:48:52 +00:00Commented Jan 31, 2014 at 2:48
-
\$\begingroup\$ Does it have to recur exactly in the top left corner \$\endgroup\$mniip– mniip2014年01月31日 05:01:06 +00:00Commented Jan 31, 2014 at 5:01
15 Answers 15
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.
GolfScript, 30 characters
~(,[0`]{{[49+]1,ドル*+}+%zip}@/n*
Example (run online):
> 7
01335555
22335555
44445555
44445555
66666666
66666666
66666666
66666666
-
\$\begingroup\$ This produces the wrong output for even numbers, such as the one in the question... \$\endgroup\$Timwi– Timwi2014年02月01日 15:24:55 +00:00Commented 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– Howard2014年02月02日 11:28:53 +00:00Commented Feb 2, 2014 at 11:28
-
\$\begingroup\$ Alright, I guess I was too strict then :) \$\endgroup\$Timwi– Timwi2014年02月02日 17:03:34 +00:00Commented 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\$Martin Ender– Martin Ender2015年01月30日 13:49:17 +00:00Commented Jan 30, 2015 at 13:49
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
-
1\$\begingroup\$ Nice. You can shorten it a bit with
for i in s:print''.join(i)
. \$\endgroup\$Daniel Lubarov– Daniel Lubarov2014年02月02日 09:03:36 +00:00Commented Feb 2, 2014 at 9:03
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
-
\$\begingroup\$ What does the output of this look like? \$\endgroup\$user8777– user87772014年01月31日 03:38:01 +00:00Commented Jan 31, 2014 at 3:38
-
\$\begingroup\$ @LegoStormtroopr added some examples, it's the exact same format as the question though. \$\endgroup\$Paul Prestidge– Paul Prestidge2014年01月31日 04:00:41 +00:00Commented Jan 31, 2014 at 4:00
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
-
\$\begingroup\$ C and D both extend horizontally. They should alternate horizontally and vertically. \$\endgroup\$Hand-E-Food– Hand-E-Food2014年02月01日 11:46:56 +00:00Commented 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– barbermot2014年02月01日 13:08:48 +00:00Commented Feb 1, 2014 at 13:08
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
-
\$\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– flawr2015年01月30日 20:41:57 +00:00Commented Jan 30, 2015 at 20:41 -
\$\begingroup\$ @flawr: Oh! Obviously! \$\endgroup\$knedlsepp– knedlsepp2015年01月30日 21:02:43 +00:00Commented Jan 30, 2015 at 21:02
-
\$\begingroup\$ Save another byte by replacing the argument of
fix
withfix(n/2-[.5,1])
PS: Really nice solution withcat
, did not know about this use where you can choose the dimension=) \$\endgroup\$flawr– flawr2015年01月30日 21:05:15 +00:00Commented Jan 30, 2015 at 21:05 -
\$\begingroup\$ @flawr: It seems to me I'm quite wasteful. ;-) \$\endgroup\$knedlsepp– knedlsepp2015年01月30日 21:06:45 +00:00Commented 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– flawr2015年01月30日 21:36:35 +00:00Commented Jan 30, 2015 at 21:36
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"
Sclipting, 59 characters
❶塊갠分감⓶左貶終辦감標가⓺貶⓹開上❶❶貶雙是不2.갠乘2.終가1上뀀❷2갠分小是增終❸⓷另要감右⓶갠加⓶終丟字⓶終丟겠終
(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;
❶❶貶雙是不2.갠乘2.終 | w d M [s] y
for (x in [0..w])
가1上 | w d M [s] y x
c = 64; // '@'
뀀 | w d M [s] y x c
if (x < d/2) c++;
❷2갠分小是增終 | 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:
一丁七七丅丅丅丅万万万万万万万万
丂丂七七丅丅丅丅万万万万万万万万
丄丄丄丄丅丅丅丅万万万万万万万万
丄丄丄丄丅丅丅丅万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丆丆丆丆丆丆丆丆万万万万万万万万
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈丈
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:
!"$$&&&&((((((((****************
##$$&&&&((((((((****************
%%%%&&&&((((((((****************
%%%%&&&&((((((((****************
''''''''((((((((****************
''''''''((((((((****************
''''''''((((((((****************
''''''''((((((((****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
))))))))))))))))****************
-
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– Bob2014年01月31日 06:33:01 +00:00Commented Jan 31, 2014 at 6:33 -
\$\begingroup\$ Thanks @Bob! I must have miscounted while micro-optimizing. \$\endgroup\$Hand-E-Food– Hand-E-Food2014年02月01日 11:44:22 +00:00Commented Feb 1, 2014 at 11:44
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
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
Sclipting, 45 characters
가⓶貶上倘감雙⓶壹長⓸講增字⓶復⓷是標⓷各1合終并不⓶梴❸⓶疊合終不뀐標뀐并終終⓶丟各겠終
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
標⓷各1合終并
else
不
concatenate c.Repeat(list.Length) onto list
⓶梴❸⓶疊合
終
else (i.e., i == 0)
不
c = "A"
뀐
list = ["A"]
標뀐并
終
終
concatenate "\n" to every element in list
⓶丟各겠終
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.
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*
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.