11
\$\begingroup\$

Disclaimer: The story told within this question is entirely fictional, and invented solely for the purpose of providing an intro.

I have a friend who is an architect, and, after explaining the concept of code-golf and this site to him, he said that I should code something actually useful for a change. I asked him what he would consider useful, and, being an architect, he replied that he would enjoy having a floor planner that gave him all possible arrangements for rooms of certain sizes within a house of a certain size. I thought I would prove that code-golf wasn't useless after all, and give him this program in the smallest number of bytes possible.

Your Task:

Write a program or function that, when given an array D containing the dimensions of the entire house, and a second array R containing the dimensions of the interior rooms, output as ASCII art, all possible configurations of the rooms inside the house.

All rooms and the exterior walls of the house should be formed as standard ASCII boxes, using the | symbol for vertical walls, the - symbol as horizontal walls, and the + symbol for corners. For example, a house with the dimensions [4,4] will look like:

+----+
|    |
|    |
|    |
|    |
+----+

As you can see, corners do not count as part of a set of dimensions. The number of - or | characters forming a side should equal the number given in the dimensions. Rooms may share walls, or share walls with the house. A room may not contain smaller rooms within itself.

For example, the configuration

+--+---+-+
|  |   | |
|  |   | |
+--+---+ |
|        |
|        |
+--------+

is valid for D=[5,8], and R=[[2,2],[2,3]].

Input:

Two arrays, one of which contains two integers, the dimensions for the house, and the other of which contains a series of arrays containing the dimensions for rooms.

Output:

Either an array of all possible houses as strings, or a string containing all possible houses, delimited in some consistent way. Note that rotations of the exact same configuration should only be counted once.

Test Cases:

D     R                   ->   Output

[4,3] [[2,1],[4,1]]       -> +-+-+ +-+-+ +-+-+  Note that though there is an option to switch which side the [2,1] room and the [4,1] room are on, doing so would merely be rotating the house by 180 degrees, and therefore these possibilities do not count.  
                             | | | +-+ | | | |
                             +-+ | | | | | | |
                             | | | | | | +-+ |
                             | | | +-+ | | | |
                             +-+-+ +-+-+ +-+-+

[4,7] [[3,1],[4,2],[2,2]  -> +----+--+ +----+--+ +----+--+ +----+--+  There are some more possiblities I didn't feel like adding, but it's the same four again, just with the [4,2] and the [2,2] room switched.  
                             |    |  | |    |  | |    |  | |    |  |
                             |    |  | |    |  | |    |  | |    |  |
                             +---++--+ +--+-+-++ +-+--++-+ ++---+--+
                             |   |   | |  |   || | |   | | ||   |  |
                             +---+---+ +--+---++ +-+---+-+ ++---+--+

Scoring:

This is , lowest score in bytes wins!

\$\endgroup\$
  • \$\begingroup\$ Does mirroring count as the same configuration? \$\endgroup\$ – user72349 Aug 2 '17 at 1:23
  • \$\begingroup\$ No. You must reproduce mirrored configurations. \$\endgroup\$ – Gryphon - Reinstate Monica Aug 2 '17 at 1:24
  • 4
    \$\begingroup\$ Your first test case isn't false ? D = [4,2], but your house is [4,3], isn't it ? \$\endgroup\$ – HatsuPointerKun Aug 2 '17 at 1:29
  • \$\begingroup\$ @HatsuPointerKun, thank-you for finding that typo. It is now fixed. \$\endgroup\$ – Gryphon - Reinstate Monica Aug 2 '17 at 11:17
  • 2
    \$\begingroup\$ It's indeed a well known fact that architects do most of their designs with ASCII art in Notepad. \$\endgroup\$ – Sanchises Aug 4 '17 at 8:14
2
\$\begingroup\$

Python 2, 625 607 602 563 551 bytes

  1. -5 bytes thanks to Mr.Xcoder.
  2. -12 bytes when avoiding deep-copying.
  3. -39 bytes with some list simplifications.
r,z=range,len
L,C=D;p,q,v,w=['+'],['|'],'*',' '
H=[p+['-']*C+p]
P=[[e[:]for e in H+[q+[w]*C+q]*L+H]]
def g(M,x,y,N):
 m=[e[:]for e in M]
 try:
  for i in r(z(N)):
   for j in r(z(N[0])):
	if v==N[i][j]and w!=M[x+i][y+j]:return[]
	m[x+i][y+j]=m[x+i][y+j]in[w,v,N[i][j]]and N[i][j]or'+'
 except:return[]
 return m
for l,c in R:
 H=[p+['-']*c+p]
 P=[g(U,x,y,[e[:]for e in H+[q+[v]*c+q]*l+H])for U in P for x in r(L+2)for y in r(C+2)]
F=[]
for m in P:
 if[e[::-1]for e in m[::-1]]not in F:F+=[m]
for m in F:
 print
 for e in m:print''.join(e).replace(v,w)

Try it online!

Some explanations It is a greedy approach:

  1. Find all positions where the first room can be allocated
  2. Find all possible positions where the next room can be allocated from the remaining free space of the house, and so on for the other rooms.
  3. If the last room was successfully allocated the code output the configuration if it is not a 180°-rotation of a previous configuration.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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