Render an ASCII maze
APL (Dyalog Unicode), 57 35 bytesSBCS
–22 thanks to a novel solution by ngn.
Anonymous tacit function taking a character matrix as argument.
{⊃'+-|+'↓⍨2⊥5 4 2⊃¨⊂⍱∘⌽⍨' '≠,⍵}⌺3 3
Try it online!
{
…}⌺3 3
on each 3-by-3 neighbourhood, apply the following function:
,⍵
ravel (flatten)
' '≠
Boolean where non-space
⍱∘⌽⍨
that NOR it's reverse (incl. neither top NOR bottom, neither left NOR right)
5 4 2⊃¨⊂
pick 5th, 4th, and 2nd element from that entire list
i.e. empty self, no vertical, no horizontal
2⊥
evaluate in base-2 (binary)
i.e. ≥4:empty self; 3:no neighbours; 2:no horizontal neighbours; 1:no vertical; 0: has both
'+-|+'↓⍨
drop that many elements from this string
i.e. empty self:; alone:
+
; vertical neighbour(s) only:|+
; horizontal:-|+
; both:+-|+
⊃
pick the first element (pad with space if non are available)
i.e. empty self:
; alone:+
; vertical neighbour(s) only:|
; horizontal:-
; both:+
Old solution
Anonymous tacit function taking a character matrix as argument.
{' +-|+'⊃⍨1⍳⍨(' '=5⊃,⍵),(∧/,⊢)∨/2 2⍴1⌽' '≠(9⍴0 1)/,⍵}⌺3 3
Try it online!
{
…}⌺3 3
on each 3-by-3 neighbourhood, apply the following function:
,⍵
ravel (flatten)
(
…)/
filter using the following mask:
9⍴0 1
cyclically reshape [0,1]
to length 9 (selects N, W, E, S)
' '≠
Boolean where non-space
1⌽
rotate one step left; [W,E,S,N]
2 2⍴
reshape to 2-by-2 matrix; [[W,E],[S,N]]
∨/
row-wise OR reduction: [horizontal,vertical]
(
…)
apply the following tacit function:
⊢
the identity; [horizontal,vertical]
∧/,
preceded by its AND reduction; [both,horizontal,vertical]
(
…),
prepend the following:
,⍵
ravel (flatten) the neighbourhood
5⊃
pick the 5th element (itself)
' '=
Boolean if space (i.e. empty)
Now we have [empty,both,horizontal,vertical]
1⍳⍨
index of leftmost 1 (gives 5 if no neighbours at all)
' +-|+'⊃⍨
use that to pick symbol
Python 2, 181 168 bytes
thanks to Leaky Nun for -13 bytes
m=input()
f=lambda x,y:(['']+m+[''])[y+1][x:x+1]>' '
print[[(c<'!')*' 'or'+-|+'[f(x+1,y)|f(x-1,y)|2*f(x,y+1)|2*f(x,y-1)]for x,c in enumerate(r)]for y,r in enumerate(m)]
Try it online!
JavaScript (ES6), 110 bytes
I/O format: array of strings.
a=>a.map((s,y)=>s.replace(/\S/g,(_,x)=>'+|-+'[[-1,p=0,1,2].map(c=>p|=(a[y+c%2]||0)[x+~-c%2]>' '?c&1||2:0)|p]))
Try it online!
Or 108 bytes by using a matrix of characters instead.