# Tiling a 2^N by 2^N Grid with L-Shaped Trominoes

When students are first taught about the proof technique of mathematical induction, a common example is the problem of tiling a 2N×2N grid with L-shaped trominoes, leaving one predetermined grid space empty. (N is some nonnegative integer.)

I will leave it to you to go over the proof if you do not already know it. There are many resources that discuss it.

Your task here is to write a program that takes in a value for N, as well as the coordinates of the grid space to leave empty, and prints an ASCII representation of the resulting tromino tiled grid.

The character O will fill the empty space, and the 4 rotations of our tromino will look like this:

|
+-

|
-+

-+
|

+-
|


(Yes, it can be ambiguous which + goes with which - and | for certain arrangements, but that's ok.)

Your program must work for N = 0 (for a 1×1 grid) up to at least N = 8 (for a 256×256 grid). It will be given x and y values that are the coordinates for the O:

• x is the horizontal axis. x = 1 is the left grid edge, x = 2N is the right grid edge.
• y is the vertical axis. y = 1 is the top grid edge, y = 2N is the bottom grid edge.

Both x and y are always in the range [1, 2N].

So for a given N, x, and y, your program must print a 2N×2N grid, tiled completely with L-shaped trominoes, except for the x, y grid coordinate which will be an O.

## Examples

If N = 0, then x and y must both be 1. The output is simply

O


If N = 1, x = 1, and y = 2, the output would be

-+
O|


N = 2, x = 3, y = 2:

+--+
||O|
|+-|
+--+


N = 2, x = 4, y = 1:

+-|O
||+-
|+-|
+--+


N = 3, x = 3, y = 6 (e.g. the image on this page):

+--++--+
|+-||-+|
||+--+||
+-|-+|-+
+--+||-+
||O|-+||
|+-||-+|
+--++--+


## Details

• You may write a function that takes the 3 integers instead of writing an entire program. It should print or return the grid string.
• Take input from stdin, command line, (or function args if you write function).
• The output may optionally contain a single training newline.
• You are not required to use the tiling method that the proof normally suggests. It only matters that the grid is filled with L-shaped trominoes besides the O. (Trominoes may not be cut or go out of the grid bounds.)

The shortest code in bytes wins. Tiebreaker is earlier post. (Handy byte counter.)

c=cycle
z o(#)(x,y)=zipWith o(1#x)(2#y)
f n x y=unlines$(z(+)(\m w->[c[0,m]!!div(w-1)(2^(n-k))|k<-[1..n]])(x,y),"O")%n (_,x)%0=[x] ((p:o),x)%k=z(++)(\_ q->((o,x):c[(c[3-q],[" |-+| +--+ |+-|"!!(4*p+q)])])!!abs(p-q)%(k-1))=<<[(0,1),(2,3)]  This follows the inductive solution to the problem closely. The point to mark is represented by a sequence of numbers from 0 to 3 which indicate which quadrant holds the point at each zoom level; this is initially calculated by the expression starting with z(+). The operator (%) combines pictures for the four quadrants into a single picture. Pictures for the unmarked quadrants are generated by drawing marked quadrants with the mark somewhere near the middle, drawn with a mark of "+-|" as appropriate to build the central L tile. Funny business: For golf reasons, the subexpression \m w->[c[0,m]!!div(w-1)(2^(n-k))|k<-[1..n]]  (which more or less computes the bit sequence for a number) is hilariously inefficient --- it determines if w / 2^p is odd or even by looking up the (w / 2^p)th element of a list. Edit: Saved 10 bytes by inlining the bit calculation and replacing an if/then/else with an indexing operation. Edit2: Saved four more bytes by switching a function back to an operator. @randomra, the race is on! Demo: λ> putStr$ f 4 5 6
+--++--++--++--+
|+-||-+||+-||-+|
||+--+||||+--+||
+-|+-|-++-|-+|-+
+-||-+-++--+||-+
||+-O||||-+|-+||
|+-||-+|-+|||-+|
+--++--+||-++--+
+--++-|-+|-++--+
|+-|||+--+|||-+|
||+-|+-||-+|-+||
+-||+--++--+||-+
+-|+-|-++-|-+|-+
||+--+||||+--+||
|+-||-+||+-||-+|
+--++--++--++--+


# C, 399 bytes

char*T=" |-+ | +-| ",*B;w;f(N,x,y,m,n,F,h,k,i,j){w=B?F=0,w:1<<N|1;char b[N?w*w:6];for(k=w;k--;)b[k*w-1]=10;B=!B?F=1,m=0,n=0,x--,y--,b:B;if(N>1){h=1<<N-1;i=x>--h,j=y>h;while(++k<4)if(k%2-i||k/2-j)f(N-1,!(k%2)*h,!(k/2)*h,m+k%2*(h+1),n+k/2*(h+1));f(1,h&i,h&j,m+h,n+h);h++;f(N-1,x-h*i,y-h*j,m+h*i,n+h*j);}else while(++k<4)B[w*(n+k/2)+m+k%2]=T[5*x+2*y+k];if(F)B[y*w+x]=79,B[w*w-w-1]=0,puts(N?B:"O"),B=0;}


No one's come forward with anything yet, so I'll offer up a meager solution. Mark my words, this is not the end. This will get shorter.

We define a function f that takes 10 arguments, but you need only call it with f(N, X, Y). Output goes to stdout.

char*T=" |-+ | +-| ",*B;
w;
f(N,x,y,m,n,F,h,k,i,j){
w=B?F=0,w:1<<N|1;
char b[N?w*w:6];
for(k=w;k--;)
b[k*w-1]=10;
B=!B?F=1,m=0,n=0,x--,y--,b:B;
if(N>1){
h=1<<N-1;
i=x>--h,j=y>h;
while(++k<4)
if(k%2-i||k/2-j)
f(N-1,!(k%2)*h,!(k/2)*h,m+k%2*(h+1),n+k/2*(h+1));
f(1,h&i,h&j,m+h,n+h);
h++;
f(N-1,x-h*i,y-h*j,m+h*i,n+h*j);
}
else
while(++k<4)
B[w*(n+k/2)+m+k%2]=T[5*x+2*y+k];
if(F)B[y*w+x]=79,B[w*w-w-1]=0,puts(N?B:"O"),B=0;
}


A taste of output for f(3, 2, 7):

+--++--+
|+-||-+|
||+--+||
+-|-+|-+
+--+||-+
|-+|-+||
|O|||-+|
+--++--+


It's a fairly simple recursive algorithm to fill the grid. I may upload an animation of the algorithm drawing trominoes since I think it's pretty neat. As usual, feel free to ask questions and shout at me if my code breaks!

Try it online!

# Python 3, 276265 237 bytes

My first Python golf so I'm sure there is a lot of room for improvement.

def f(n,x,y,c='O'):
if n<1:return c
*t,l,a='x|-+-|',2**~-n;p=(a<x)+(a<y)*2
for i in 0,1,2,3:t+=(p-i and f(n-1,1+~i%2*~-a,1+~-a*(1-i//2),l[p+i])or f(n-1,1+~-x%a,1+~-y%a,c)).split(),
u,v,w,z=t;return'\n'.join(map(''.join,zip(u+w,v+z)))


10 bytes saved thanks to @xnor and 6 more bytes thanks to @Sp3000.

The function returns a string. Example usage:

>>>print(f(3,3,6))
+--++--+
|+-||-+|
||+--+||
+-|-+|-+
+--+||-+
||O|-+||
|+-||-+|
+--++--+

• An impressive first run at Python golfing! Some quick charsaves. You can cut the space before if p!=i; the list inside .join() doesn't need []; (1-i%2) can be done as ~i%2; you can use iterable unpacking to write t,l,a=[],... as *t,l,a=...; if n==0 can be checked as if n<1 because n can't be negative; the final "\n".join can probably be done by printing each element, since general rules allow printing in place of returning; if p!=i can be if p-i because nonzero values are Truthy. – xnor Apr 21 '15 at 10:04
• @xnor Thanks for the tips! The unpacking to get an implicit empty list is very neat. I use return instead of print as f is a recursive function. I actually have to revert the output formatting with split() after every self-call. – randomra Apr 21 '15 at 11:00
• A few more: The last line can be written as A,B,C,D=t;return'\n'.join(map("".join,zip(A+C,B+D))), t+=[...] on the second-last line can be written as t+=..., (adding a tuple instead of a list) and I'm not sure if this one works but A if B else C can be written as B and A or C (also on the second-last line), but only if A is never falsy (which I don't think it is?) – Sp3000 Apr 21 '15 at 11:03

# JavaScript (ES6) 317 414

A lot of work to golf, but still quite long.

T=(b,x,y)=>
(F=(d,x,y,f,t=[],q=y<=(d>>=1)|0,
b=d?x>d
?q
?F(d,x-d,y,0,F(d,1,1,2))
:F(d,1,d,2,F(d,x-d,y-d))
:F(d,1,d,1-q,F(d,1,1,q)):0,
r=d?(x>d
?F(d,d,d,1-q,F(d,d,1,q))
:q
?F(d,x,y,1,F(d,d,1,2))
:F(d,d,d,2,F(d,x,y-d))
).map((x,i)=>x.concat(b[i])):[[]]
)=>(r[y-1][x-1]='|+-O'[f],r.concat(t))
)(1<<b,x,y,3).join('\n').replace(/,/g,'')


Run snippet to test (better looking using Unicode block characters - but even a bit longer)

T=(b,x,y)=>
(F=(d,x,y,f,t=[],q=y<=(d>>=1)|0,
b=d?x>d
?q
?F(d,x-d,y,0,F(d,1,1,6))
:F(d,1,d,6,F(d,x-d,y-d))
:F(d,1,d,q,F(d,1,1,q+1)):0,
r=d?(x>d
?F(d,d,d,q+3,F(d,d,1,q+4))
:q
?F(d,x,y,1,F(d,d,1,6))
:F(d,d,d,6,F(d,x,y-d))
).map((x,i)=>x.concat(b[i])):[[]]
)=>(
r[y-1][x-1]='┐│┘┌│└─O'[f],r.concat(t)
))(1<<b,x,y,7).join('\n').replace(/,/g,'')

loop=_=>{
var x=X.value|0, y=Y.value|0, n=N.value|0;

var b=1<<n, cur=1<<(n+n);
(L=_=>{
--cur;
O.innerHTML=T(n,(cur&(b-1))+1,(cur>>n)+1);
cur&&setTimeout(L,100);
})()
}

tile=_=>{
var x=X.value|0, y=Y.value|0, n=N.value|0;
O.innerHTML=T(n,x,y);
}

tile()
input { width: 3em }
pre { font-size: 10px; line-height: 10px }
N: <input id=N value=4> X: <input id=X value=5> Y: <input id=Y value=3>
<button onclick="tile()">Tile</button>
<button onclick="loop()">Loop</button>
<pre id=O></pre>

# IDL 8.3+, 293 bytes

This is too long, I'm trying to cut it down but I haven't gotten there yet.

function t,n,x,y
m=2^n
c=['|','+','-']
b=replicate('0',m,m)
if m eq 1 then return,b
h=m/2
g=h-1
k=[1:h]
o=x gt h
p=y gt h
q=o+2*p
if m gt 2then for i=0,1 do for j=0,1 do b[i*h:i*h+g,j*h:j*h+g]=t(n-1,i+2*j eq q?x-i*h:k[i-1],i+2*j eq q?y-j*h:k[j-1])
b[g+[1-o,1-o,o],g+[p,1-p,1-p]]=c
return,b
end


Outputs:

IDL> print,t(1,1,2)
- +
0 |
IDL> print,t(2,3,2)
+ - - +
| | 0 |
| + - |
+ - - +
IDL> print,t(2,4,1)
+ - | 0
| | + -
| + - |
+ - - +
IDL> print,t(3,3,6)
+ - - + + - - +
| + - | | - + |
| | + - - + | |
+ - | - + | - +
+ - - + | | - +
| | 0 | - + | |
| + - | | - + |
+ - - + + - - +


And, uh... just for fun...

IDL> print,t(6,8,9)
+ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - +
| + - | | - + | | + - | | - + | | + - | | - + | | + - | | - + | | + - | | - + | | + - | | - + | | + - | | - + | | + - | | - + |
| | + - - + | | | | + - - + | | | | + - - + | | | | + - - + | | | | + - - + | | | | + - - + | | | | + - - + | | | | + - - + | |
+ - | + - | - + + - | - + | - + + - | + - | - + + - | - + | - + + - | + - | - + + - | - + | - + + - | + - | - + + - | - + | - +
+ - | | + - - + + - - + | | - + + - | | + - - + + - - + | | - + + - | | + - - + + - - + | | - + + - | | + - - + + - - + | | - +
| | + - | + - | | - + | - + | | | | + - | + - | | - + | - + | | | | + - | + - | | - + | - + | | | | + - | + - | | - + | - + | |
| + - | | | + - - + | | | - + | | + - | | | + - - + | | | - + | | + - | | | + - - + | | | - + | | + - | | | + - - + | | | - + |
+ - - + + - | - + | - + + - - + + - - + + - | - + | - + + - - + + - - + + - | + - | - + + - - + + - - + + - | - + | - + + - - +
+ - - + + - | 0 | | - + + - - + + - - + + - - + | | - + + - - + + - - + + - | | + - - + + - - + + - - + + - - + | | - + + - - +
| + - | | | + - - + | | | - + | | + - | | - + | - + | | | - + | | + - | | | + - | + - | | - + | | + - | | - + | - + | | | - + |
| | + - | + - | | - + | - + | | | | + - - + | | | - + | - + | | | | + - | + - | | | + - - + | | | | + - - + | | | - + | - + | |
+ - | | + - - + + - - + | | - + + - | - + | - + + - - + | | - + + - | | + - - + + - | + - | - + + - | - + | - + + - - + | | - +
+ - | + - | - + + - | - + | - + + - - + | | - + + - | - + | - + + - | + - | - + + - | | + - - + + - - + | | - + + - | - + | - +
| | + - - + | | | | + - - + | | | - + | - + | | | | + - - + | | | | + - - + | | | | + - | + - | | - + | - + | | | | + - - + | |
| + - | | - + | | + - | | - + | - + | | | - + | | + - | | - + | | + - | | - + | | + - | | | + - - + | | | - + | | + - | | - + |
+ - - + + - - + + - - + + - - + | | - + + - - + + - - + + - - + + - - + + - - + + - - + + - | - + | - + + - - + + - - + + - - +
+ - - + + - - + + - - + + - | - + | - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + | | - + + - - + + - - + + - - +
| + - | | - + | | + - | | | + - - + | | | - + | | + - | | - + | | + - | | - + | | + - | | - + | - + | | | - + | | + - | | - + |
| | + - - + | | | | + - | + - | | - + | - + | | | | + - - + | | | | + - - + | | | | + - - + | | | - + | - + | | | | + - - + | |
+ - | + - | - + + - | | + - - + + - - + | | - + + - | - + | - + + - | + - | - + + - | - + | - + + - - + | | - + + - | - + | - +
+ - | | + - - + + - | + - | - + + - | - + | - + + - - + | | - + + - | | + - - + + - - + | | - + + - | - + | - + + - - + | | - +
| | + - | + - | | | + - - + | | | | + - - + | | | - + | - + | | | | + - | + - | | - + | - + | | | | + - - + | | | - + | - + | |
| + - | | | + - | + - | | - + | | + - | | - + | - + | | | - + | | + - | | | + - - + | | | - + | | + - | | - + | - + | | | - + |
+ - - + + - | | + - - + + - - + + - - + + - - + | | - + + - - + + - - + + - | - + | - + + - - + + - - + + - - + | | - + + - - +
+ - - + + - | + - | - + + - - + + - - + + - | - + | - + + - - + + - - + + - - + | | - + + - - + + - - + + - | - + | - + + - - +
| + - | | | + - - + | | | - + | | + - | | | + - - + | | | - + | | + - | | - + | - + | | | - + | | + - | | | + - - + | | | - + |
| | + - | + - | | - + | - + | | | | + - | + - | | - + | - + | | | | + - - + | | | - + | - + | | | | + - | + - | | - + | - + | |
+ - | | + - - + + - - + | | - + + - | | + - - + + - - + | | - + + - | - + | - + + - - + | | - + + - | | + - - + + - - + | | - +
+ - | + - | - + + - | - + | - + + - | + - | - + + - | - + | - + + - - + | | - + + - | - + | - + + - | + - | - + + - | - + | - +
| | + - - + | | | | + - - + | | | | + - - + | | | | + - - + | | | - + | - + | | | | + - - + | | | | + - - + | | | | + - - + | |
| + - | | - + | | + - | | - + | | + - | | - + | | + - | | - + | - + | | | - + | | + - | | - + | | + - | | - + | | + - | | - + |
+ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + | | - + + - - + + - - + + - - + + - - + + - - + + - - + + - - +
+ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - | - + | - + + - - + + - - + + - - + + - - + + - - + + - - + + - - +
| + - | | - + | | + - | | - + | | + - | | - + | | + - | | | + - - + | | | - + | | + - | | - + | | + - | | - + | | + - | | - + |
| | + - - + | | | | + - - + | | | | + - - + | | | | + - | + - | | - + | - + | | | | + - - + | | | | + - - + | | | | + - - + | |
+ - | + - | - + + - | - + | - + + - | + - | - + + - | | + - - + + - - + | | - + + - | - + | - + + - | + - | - + + - | - + | - +
+ - | | + - - + + - - + | | - + + - | | + - - + + - | + - | - + + - | - + | - + + - - + | | - + + - | | + - - + + - - + | | - +
| | + - | + - | | - + | - + | | | | + - | + - | | | + - - + | | | | + - - + | | | - + | - + | | | | + - | + - | | - + | - + | |
| + - | | | + - - + | | | - + | | + - | | | + - | + - | | - + | | + - | | - + | - + | | | - + | | + - | | | + - - + | | | - + |
+ - - + + - | + - | - + + - - + + - - + + - | | + - - + + - - + + - - + + - - + | | - + + - - + + - - + + - | - + | - + + - - +
+ - - + + - | | + - - + + - - + + - - + + - | + - | - + + - - + + - - + + - | - + | - + + - - + + - - + + - - + | | - + + - - +
| + - | | | + - | + - | | - + | | + - | | | + - - + | | | - + | | + - | | | + - - + | | | - + | | + - | | - + | - + | | | - + |
| | + - | + - | | | + - - + | | | | + - | + - | | - + | - + | | | | + - | + - | | - + | - + | | | | + - - + | | | - + | - + | |
+ - | | + - - + + - | + - | - + + - | | + - - + + - - + | | - + + - | | + - - + + - - + | | - + + - | - + | - + + - - + | | - +
+ - | + - | - + + - | | + - - + + - | + - | - + + - | - + | - + + - | + - | - + + - | - + | - + + - - + | | - + + - | - + | - +
| | + - - + | | | | + - | + - | | | + - - + | | | | + - - + | | | | + - - + | | | | + - - + | | | - + | - + | | | | + - - + | |
| + - | | - + | | + - | | | + - | + - | | - + | | + - | | - + | | + - | | - + | | + - | | - + | - + | | | - + | | + - | | - + |
+ - - + + - - + + - - + + - | | + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + | | - + + - - + + - - + + - - +
+ - - + + - - + + - - + + - | + - | - + + - - + + - - + + - - + + - - + + - - + + - - + + - | - + | - + + - - + + - - + + - - +
| + - | | - + | | + - | | | + - - + | | | - + | | + - | | - + | | + - | | - + | | + - | | | + - - + | | | - + | | + - | | - + |
| | + - - + | | | | + - | + - | | - + | - + | | | | + - - + | | | | + - - + | | | | + - | + - | | - + | - + | | | | + - - + | |
+ - | + - | - + + - | | + - - + + - - + | | - + + - | - + | - + + - | + - | - + + - | | + - - + + - - + | | - + + - | - + | - +
+ - | | + - - + + - | + - | - + + - | - + | - + + - - + | | - + + - | | + - - + + - | + - | - + + - | - + | - + + - - + | | - +
| | + - | + - | | | + - - + | | | | + - - + | | | - + | - + | | | | + - | + - | | | + - - + | | | | + - - + | | | - + | - + | |
| + - | | | + - | + - | | - + | | + - | | - + | - + | | | - + | | + - | | | + - | + - | | - + | | + - | | - + | - + | | | - + |
+ - - + + - | | + - - + + - - + + - - + + - - + | | - + + - - + + - - + + - | | + - - + + - - + + - - + + - - + | | - + + - - +
+ - - + + - | + - | - + + - - + + - - + + - | - + | - + + - - + + - - + + - | + - | - + + - - + + - - + + - | - + | - + + - - +
| + - | | | + - - + | | | - + | | + - | | | + - - + | | | - + | | + - | | | + - - + | | | - + | | + - | | | + - - + | | | - + |
| | + - | + - | | - + | - + | | | | + - | + - | | - + | - + | | | | + - | + - | | - + | - + | | | | + - | + - | | - + | - + | |
+ - | | + - - + + - - + | | - + + - | | + - - + + - - + | | - + + - | | + - - + + - - + | | - + + - | | + - - + + - - + | | - +
+ - | + - | - + + - | - + | - + + - | + - | - + + - | - + | - + + - | + - | - + + - | - + | - + + - | + - | - + + - | - + | - +
| | + - - + | | | | + - - + | | | | + - - + | | | | + - - + | | | | + - - + | | | | + - - + | | | | + - - + | | | | + - - + | |
| + - | | - + | | + - | | - + | | + - | | - + | | + - | | - + | | + - | | - + | | + - | | - + | | + - | | - + | | + - | | - + |
+ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - +


# Ruby Rev 1, 288

As an anonymous lambda literal. Shown in test program (the lambda literal is ->(n,a,b){...} )

g=
->(n,a,b){
$x=a-1$y=b-1
$a=Array.new(m=2**n){"|"*m} def t(u,v,m,r,f) (m/=2)==1?$a[v+1-r/2%2][u,2]='-+-'[r%2,2]:0
if m>1
4.times{|i|i==r ?t(u+m/2,v+m/2,m,r,0):t(u+i%2*m,v+i/2*m,m,3-i,0)}
f>0?t(u+r%2*m,v+r/2*m,m,2*$x/m&1|$y*4/m&2,1):0
end
end
t(0,0,m,2*$x/m|$y*4/m,1)
$a[$y][$x]='O'$a
}

n=gets.to_i
a=gets.to_i
b=gets.to_i
puts(g.call(n,a,b))


# Ruby Rev 0, 330 ungolfed

Currently the only golfing I'm claiming is elimination of comments, unnecessary newlines and indents.

This is my first proper algorithm encoded in Ruby and it's been hard work. I'm sure there's at least 50 characters than can be eliminated, but I've done enough for now. There are some real horrors, for example the input. That can probably be fixed by a function or lambda instead of a program, but the inner function t that draws the trominoes still needs access to the global variables. I'll have to figure out the syntax for that.

A feature of my answer which is not present in the others, is that I initialize an array of strings with | characters. That means I only have to draw the +- or -+, which are next to each other on the same line.

m=2**gets.to_i                                         #get n and store 2**n in m
$x=gets.to_i-1 #get x and y, and...$y=gets.to_i-1                                         #convert from 1-indexed to 0-indexed
$a=Array.new(m){"|"*m} #array of m strings length m, initialized with "|" def t(u,v,m,r,f) #u,v=top left of current field. r=0..3= quadrant containing O. f=flag to continue surrounding O m/=2 if m==1 then$a[v+1-r/2%2][u,2] ='-+-'[r%2,2];end    #if we are at char level, insert -+ or +- (array already initialized with |'s)
if m>1 then                                          #at higher level, 4 recursive calls to draw trominoes of next size down
4.times{|i| i==r ? t(u+m/2,v+m/2,m,r,0):t(u+i%2*m,v+i/2*m,m,3-i,0)}
f>0?t(u+r%2*m,v+r/2*m,m,2*$x/m&1|$y*4/m&2,1):0     #then one more call to fill in the empty quadrant (this time f=1)
end
end

$a[$y][$x]='O' #fill in O t(0,0,m,2*$x/m&1|$y*4/m&2,1) #start call. 2*x/m gives 0/1 for left/right quadrant, similarly 4*y/m gives 0/2 for top/bottom puts$a                                                #dump array to stdout, elements separated by newlines.


r=reverse
g n s x y|n<1=[s]|x>k=r<$>g n s(2^n+1-x)y|y>k=r$g n s x$2^n+1-y|0<1=zipWith(++)(h s x y++h"-"k 1)$h"|"1 k++h"+"1 1 where m=n-1;k=2^m;h=g m
f n x=unlines.g n"O"x


Run online at Ideone

Example run:

*Main> putStr(f 3 3 6)
+--++--+
|+-||-+|
||+--+||
+-|-+|-+
+--+||-+
||O|-+||
|+-||-+|
+--++--+