g | x | w | all
Bytes Lang Time Link
195Perl 5250705T140109Zgood old
456Maple250702T003055Zdharr
198JavaScript ES6250629T235924ZArnauld
800Python3250630T170230ZAjax1234
165Charcoal250629T195013ZNeil

Perl 5, 195 196 .. 253 bytes

($c,$_)='..'x((@d=/\d/g)/@{$x=eval});$_=/7|0\n|(\n.*){$#$x}3/?pop@a:$_.(($n-=/0$/+/3$c$/s)^1||!!push@a,$_.32).!$n*2while$n=0*s/$c$/2$&\n/.$d[y/13//];$_=$&.s!.+\n!$&=~y/201/| /r.$&!ger;y/1302/- +/

Try it online!

-p0 are the CLI switches. Somewhat un-golfed but not commented:

( $c, $_ ) = '..' x (( @d = /\d/g ) / @{ $x = eval });

$_ = / 7 | 0\n | (\n.*){$#$x}3 /x
    ? pop @a
    : $_ . (
            ( $n -= /0$/ + /3$c$/s ) ^ 1
                || !!push @a, $_ . 32 
           )
         . !$n * 2
while $n = 0 * s/$c$/2$&\n/ . $d[ y/13// ];

$_ = $& . s!.+\n! $& =~ y/201/| /r . $& !ger;
y/1302/- +/

Maple,  472  456 bytes

proc(s)m:=nops(s);n:=nops(s[1]);M,N:=2*m+1,2*n+1;X:=Matrix(M,N,(i,j)->`if`(`and`((i,j)::~odd),"+"," "));e:=();for p to m do for q to n do i,j:=2*p,2*q;e,=x[i,j-1]+x[i,j+1]+x[i-1,j]+x[i+1,j]=s[p,q]od od;f:={seq([x[1,p],x[M,p]][],p=2..N,2),seq([x[q,1],x[q,N]][],q=2..M,2)}=~0;Z:=subs(f,{e});Y:=indets(Z);assign(subs(x=X,map(d->`if`(rhs(d)=1,NULL,`if`(op(1,(h:=lhs(d)))::odd,h="-",h="|")),SMTLIB:-Satisfy({Z[],(Y>=~0)[],(Y<~2)[]})union f)));printf("%s",X)end;

For m rows of rooms and n columns of rooms, set up a (2m+1) x (2n+1) matrix X=(x)_{i,j} with an entry for each character in the printout. Set up spaces in room interiors and "+" at the room corners. Set up the walls for the perimeter with values 0 (0 = wall, 1 = door). So for the p,q th room (p = 1,..,m, q = 1,..,n) with given wall number s[p,q], we have x[2p,2q-1]+x[2p,2q+1]+x[2p-1,2q]+x[2p+1,2q] = s[p,q]. Solve these equations and fill in walls of the correct type.

Slightly ungolfed:

proc(s)
m:=nops(s);
n:=nops(s[1]);
M,N:=2*m+1,2*n+1;
# X is matrix of characters; start with "+" and " "
X:=Matrix(M,N,(i,j)->`if`(`and`((i,j)::~odd),"+"," "));
e:=();                      # initialize eqns to solve
for p to m do for q to n do
i,j:=2*p,2*q;
e,=x[i,j-1]+x[i,j+1]+x[i-1,j]+x[i+1,j]=s[p,q]  # eqns for door numbers
od od;
# f sets wall variables around the boundary to zero
f:={seq([x[1,p],x[M,p]][],p=2..N,2),seq([x[q,1],x[q,N]][],q=2..M,2)}=~0;
Z:=subs(f,{e});                                # set known wall vals in eqns
Y:=indets(Z);
C:=(Y>=~0)[],(Y<~2)[];                         # conditions for all variables 0 or 1            
R:=SMTLIB:-Satisfy({Z[],C});                   # find a solution
# where there are walls, substitute "|" or "-" (doors are already " ")
S:=map(d->`if`(rhs(d)=1,NULL,`if`(op(1,(h:=lhs(d)))::odd,h="-",h="|")),R union f);
assign(subs(x=X,S));
printf("%s",X)                                 # print out as string
end;

JavaScript (ES6), 198 bytes

Returns a string.

m=>{for(N=0;n=N++,s="",m.some((r,y)=>r.some(v=>v^(k=n&!!y+2*!!x++,p+=k&1?" +":"-+",q+=k&2?"  ":"| ",n>>2*r.length&!!m[y+1])+((n/=4)/2&!!r[x])-~k/2,p="+",x=q=`
`)|(y?0:t=p,s+=p+q+`|
`)););return s+t}

Try it online!

Method

We use a brute-force search that increments a counter N until its bits represent a set of doorways compatible with the input matrix.

We build the output string s while testing the bits. Each row of the input matrix is turned into two strings p and q, representing horizontal and vertical doorways respectively. The last line is a copy of the first line (saved in t), where all doors are closed.

We use 2 bits per cell to encode the doorways to the North (bit #0) and to the West (bit #1). A cleared bit means closed. A set bit means open.

We have 3 cells to test to compute the total number of doorways at a given position:

encoding

Commented

m => {                     // m[] = input matrix
for(                       // main loop
  N = 0;                   // start with a counter N set to 0
  n = N++,                 // copy N to n, then increment N
  s = "",                  // start each iteration with s = ""
  m.some((r, y) =>         // for each row r[] at index y in m[]:
    r.some(v =>            //   for each value v in r[]:
      v ^ (                //     compare v against the sum of doorways
        k = n &            //     k = doorway bitmask of the current cell:
          !!y +            //       allow bit #0 if y != 0
          2 * !!x++,       //       allow bit #1 if x != 0 (and increment x)
        p += k & 1 ? " +"  //     add " +" to p if bit #0 is set,
                   : "-+", //     or "-+" otherwise
        q += k & 2 ? "  "  //     add "  " to q if bit #1 is set,
                   : "| ", //     or "| " otherwise
                           //     test the doorways with touching cells:
        n >> 2 * r.length  //     1. the cell below
        & !!m[y + 1]       //        force a door if it's the last row
      ) + (                //
        (n /= 4) / 2       //     2. the cell to the right
        & !!r[x]           //        force a door if it's the last column
                           //        (we also update n)
      ) - ~k / 2,          //     count the doorways of the current cell
                           //     (number of bits set in k)
      p = "+",             //     start with p = "+"
      x = q = `\n`         //     start with q = "\n" and x zero'ish
    ) | (                  //   end of inner some()
      y ? 0 : t = p,       //   if this is the first row, save p in t
      s += p + q + `|\n`   //   append p, q, a pipe and a newline to s
    )                      //
  );                       // end of outer some()
);                         // end of for()
return s + t }             // return s + t

Python3, 800 bytes

from itertools import*
E=enumerate
def f(b):
 V=['+',*'+'.join('-'*len(b[0])),'+']
 U=[k for i in b for k in[V,['|',*'|'.join(' '*len(i)),'|']]]+[V]
 q=[S:={(x,y):v for x,r in E(U)for y,v in E(r)if v in['|',' ','-']}]
 M=dict(zip([i for i in q[0]if' '==q[0][i]],[j for k in b for j in k]))
 for c in q:
  T,F=[],0
  for x,y,o in[(x,y,[(x+X,y+Y)for X,Y in[(1,0),(-1,0),(0,-1),(0,1)]])for x,y in c if' '==S[(x,y)]]:
   if M[(x,y)]>(H:=sum(c[O]==' 'for O in o)):T+=[(x,y,o)]
   if M[(x,y)]<H:F=1
  if[]==T:
   for X,Y in c:U[X][Y]=c[(X,Y)]
   return'\n'.join(map(''.join,U))
  if F:continue
  x,y,o=T[0]
  for t in combinations([(X,Y)for X,Y in o if(c[(X,Y)]=='|'and 0<Y-1 and Y+1<len(U[0])-1)or(c[(X,Y)]=='-'and 0<X-1 and X+1<len(U)-1)],M[(x,y)]-sum(c[O]==' 'for O in o)):q+=[{**c,**{i:' 'for i in t}}]

Try it online!

Charcoal, 226 165 bytes

WS⊞υιυUE¹¦¹FLυFLθ«J⊖⊗κ⊖⊗ιB³¦³»≔⁰ηW‹ηLΣυ«J⊗﹪ηLθ⊗÷ηLθ≔ΦrdΣ⊟KD³✳κζ≔›ΣKKLζεWε«≔dζ≦⊖ηJ⊗﹪ηLθ⊗÷ηLθ≔¬∧Σ⊟KD³↓⁼ -Φ⪫KVω﹪μ³εP0FΦErdKD³✳λ№λ UMλ⎇⊖νI⊕μ|P¶-»FΣKKUMKD³✳§ζκ⎇⊖μI⊖λ ≦⊕η 

Try it online! Link is to verbose version of code. Takes input as a rectangular list of newline-terminated digit strings. Explanation:

WS⊞υιυ

Input the floorplan and write it to the canvas.

UE¹¦¹FLυFLθ«J⊖⊗κ⊖⊗ιB³¦³»

Space out the digits and draw boxes around each of them.

≔⁰ηW‹ηLΣυ«

Loop until all of the rooms have been processed.

J⊗﹪ηLθ⊗÷ηLθ

Jump to the current room.

≔ΦrdΣ⊟KD³✳κζ

Find the remaining possible doorways (i.e. that are down or right and lead to a room which still wants at least one more doorway).

≔›ΣKKLζε

See if there are more doorways wanted than possible.

Wε«≔dζ

While we need to backtrack, set the possible doorways to down.

≦⊖ηJ⊗﹪ηLθ⊗÷ηLθ

Move to the previous room.

≔¬∧Σ⊟KD³↓⁼ -Φ⪫KVω﹪μ³ε

See if this was a room where we chose a single right doorway but it had both doorways available, in which case we can stop backtracking.

P0

Restore the doorway count to this room.

FΦErdKD³✳λ№λ UMλ⎇⊖νI⊕μ|

Remove any previous right or down doorways.

P¶-

The above restored the down wall with |, so correct that now.

»FΣKKUMKD³✳§ζκ⎇⊖μI⊖λ ≦⊕η 

This room can now be satisfied, so create the desired number of doorways and move to the next room, clearing the doorway count.