[Question]
  [
Given an input integer `n > 1`, output an ASCII-art octagon with side lengths composed of `n` characters. See examples below:
```
n=2
 ##
#  #
#  #
 ##
n=3
  ###
 #   #
#     #
#     #
#     #
 #   #
  ###
n=4
   ####
  #    #
 #      #
#        #
#        #
#        #
#        #
 #      #
  #    #
   ####
n=5
    #####
   #     #
  #       #
 #         #
#           #
#           #
#           #
#           #
#           #
 #         #
  #       #
   #     #
    #####
and so on.
```
You can print it to STDOUT or return it as a function result.
Any amount of extraneous whitespace is acceptable, so long as the characters line up appropriately.
### Rules and I/O
* Input and output can be given by [any convenient method](http://meta.codegolf.stackexchange.com/q/2447/42963).
* You can use any printable ASCII character instead of the `#` (except space), but the "background" character must be space (ASCII 32).
* Either a full program or a function are acceptable.
* [Standard loopholes](http://meta.codegolf.stackexchange.com/q/1061/42963) are forbidden.
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") so all usual golfing rules apply, and the shortest code (in bytes) wins.
  
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 3 bytes
```
7ÝΛ
```
[Try it online!](https://tio.run/##yy9OTMpM/f/f/PDcc7P//zcFAA "05AB1E – Try It Online")
**Explanation**
```
      # implicit input as length
      # implicit input as string to print
7Ý    # range [0...7] as directions
  Λ   # canvas print
```
See [this answer](https://codegolf.stackexchange.com/a/160031/47066) to understand the 05AB1E canvas.
[Answer]
# JavaScript (ES6), ~~114~~ ~~106~~ ~~105~~ ~~104~~ 103 bytes
```
n=>(g=x=>v=x*2>w?w-x:x,F=x=>~y?`# 
`[~x?(h=g(x--))*g(y)>0&h+v!=n|n>h+v:(y--,x=w,2)]+F(x):'')(y=w=--n*3)
```
[Try it online!](https://tio.run/##ZcjBCoJAEADQu19RBDmjboRWB2HWmz8RgWK6FrIbGe4shL@@1TG8Pd69nuqxed4eL6HNtfUdeU0SFDHJiThKpS2s4JyT8lezK6rNKqjOMxfQkwIWAjFS4FDut308rUm/tfwiBydEwmSTFC9xCYx5GCI4siSEjjL0jdGjGdrdYBR0kCIG/5Mt5rCY42JOiP4D "JavaScript (Node.js) – Try It Online")
### How?
This builds the output character by character.
Given the input \$n\$, we compute:
$$n'=n-1\\w=3n'$$
For each character at \$(x,y)\$, we compute \$(h,v)\$:
$$h=w/2-\left|x-w/2\right|\\v=w/2-\left|y-w/2\right|$$
The cells belonging to the octagon satisfy one of the following conditions:
* (\$h=0\$ OR \$v=0\$) AND \$h+v\ge n'\$ (in red below)
* \$h+v=n'\$ (in orange below)
For example, with \$n=4\$ (and \$n'=3\$):
$$\begin{matrix}(0,0)&(1,0)&(2,0)&\color{red}{(3,0)}&\color{red}{(4,0)}&\color{red}{(4,0)}&\color{red}{(3,0)}&(2,0)&(1,0)&(0,0)\\
(0,1)&(1,1)&\color{orange}{(2,1)}&(3,1)&(4,1)&(4,1)&(3,1)&\color{orange}{(2,1)}&(1,1)&(0,1)\\
(0,2)&\color{orange}{(1,2)}&(2,2)&(3,2)&(4,2)&(4,2)&(3,2)&(2,2)&\color{orange}{(1,2)}&(0,2)\\
\color{red}{(0,3)}&(1,3)&(2,3)&(3,3)&(4,3)&(4,3)&(3,3)&(2,3)&(1,3)&\color{red}{(0,3)}\\
\color{red}{(0,4)}&(1,4)&(2,4)&(3,4)&(4,4)&(4,4)&(3,4)&(2,4)&(1,4)&\color{red}{(0,4)}\\
\color{red}{(0,4)}&(1,4)&(2,4)&(3,4)&(4,4)&(4,4)&(3,4)&(2,4)&(1,4)&\color{red}{(0,4)}\\
\color{red}{(0,3)}&(1,3)&(2,3)&(3,3)&(4,3)&(4,3)&(3,3)&(2,3)&(1,3)&\color{red}{(0,3)}\\
(0,2)&\color{orange}{(1,2)}&(2,2)&(3,2)&(4,2)&(4,2)&(3,2)&(2,2)&\color{orange}{(1,2)}&(0,2)\\
(0,1)&(1,1)&\color{orange}{(2,1)}&(3,1)&(4,1)&(4,1)&(3,1)&\color{orange}{(2,1)}&(1,1)&(0,1)\\
(0,0)&(1,0)&(2,0)&\color{red}{(3,0)}&\color{red}{(4,0)}&\color{red}{(4,0)}&\color{red}{(3,0)}&(2,0)&(1,0)&(0,0)\end{matrix}
$$
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 5 bytes
```
ＧＨ*Ｎ#
```
My first answer with Charcoal!
Explanation:
```
ＧＨ*Ｎ#      //Full program
ＧＨ          //Draw a hollow polygon
   *         //with 8 sides
    Ｎ       //of side length from input
      #      //using '#' character
```
[Try it online!](https://tio.run/##S85ILErOT8z5///9nuXv96zQer9nnfL//8YA "Charcoal – Try It Online")
[Answer]
# [Canvas](https://github.com/dzaima/Canvas), ~~15~~ ~~14~~ 12 [bytes](https://github.com/dzaima/Canvas/blob/master/files/chartable.md)
```
／⁸⇵╷+×＋：⤢ｎ╬┼
```
[Try it here!](https://dzaima.github.io/Canvas/?u=JXVGRjBGJXUyMDc4JXUyMUY1JXUyNTc3KyVENyV1RkYwQiV1RkYxQSV1MjkyMiV1RkY0RSV1MjU2QyV1MjUzQw__,i=NQ__,v=8)
Explanation:
```
/             a diagonal of length n
 ⁸            the input,
  ⇵           ceiling divided by 2, (storing the remainder)
   ╷          minus one
    #×        repeat "#" that many times
      +       append that to the diagonal
       :⤢n    overlap that with its transpose
          ╬┼  quad-palindromize with the overlap being the remainder stored earlier
```
[Alternative 12-byter](https://dzaima.github.io/Canvas/?u=JXVGRjBGJXUyMDc4JXUyMUY1KyVENyV1RkYxMSV1MjU0QiV1RkYxQSV1MjkyMiV1RkY0RSV1MjU2QyV1MjUzQw__,i=Mw__,v=8).
[Answer]
# [R](https://www.r-project.org/), ~~122~~ ~~117~~ 115 bytes
```
function(n){n=n-1
m=matrix(0,y<-3*n+1,y)
v=t(h<-(w=3*n/2)-abs(row(m)-1-w))
m[h*v&h+v-n|h+v<n]=' '
write(m,1,y,,"")}
```
[Try it online!](https://tio.run/##DcyxDsIgEIDhnadoOti7lotSHeFJjEM1Ehi4JhTBRn12ZPmHb/hjtZ2mal/8SH5lYPywYVIimLCk6N9wkrum88iTkjuKbBI4TVBMo@OMtNw3iGuBgKSoIIpwdWM@uCkTf1s138zQDaJEn54QZLtI2ff4qxZmFBYuWP8 "R – Try It Online")
Ports the logic from [Arnauld's answer](https://codegolf.stackexchange.com/a/175424/67312), specifically [this revision](https://codegolf.stackexchange.com/revisions/175424/4) in case there are further improvements. Another 2 bytes saved thanks to Arnauld's suggestion of inverting the logic!
[Answer]
# [Python 2](https://docs.python.org/2/), 96 bytes
```
a=b=n=input()
while a>2-n-n:a-=1;b-=a/~-n+1;s=(-~b*' '+'#').ljust(n);print s+s[-1]*(n-2)+s[::-1]
```
[Try it online!](https://tio.run/##DcexCsMgFAXQvV8hdFAjr0GHDsrrj5QOCoEYwo1UQ@iSX7fZzim/Nm9wvUdODM4oe1P6dsx5nUR8OQLBR2IbEnEcT4KxobKiMw1SSCPvUj/WZa9NQYfyzWiimvom@xkUyOnL3l/r/fkH "Python 2 – Try It Online")
[Answer]
# [Python 2](https://docs.python.org/2/), 81 bytes
```
a=d=n=input()-1
while a<=n:print' '*a+'#'+' #'[a==n]*(3*n-a+~a)+'#';d-=1;a-=d/n+1
```
[Try it online!](https://tio.run/##FclLCoAgEADQfacQWowfJKxW2ZwkWgwYKMQkYUSbrm70ti8/JR7c10oYkDFxvopU1jV3TPsmaEae8pm4gABNBlowIFpYCJFXLQfNlsxL6h8fLDpPFkPHxtU6fg "Python 2 – Try It Online")
---
**[Python 2](https://docs.python.org/2/), 75 bytes**
```
a=d=n=input()-1
while a<=n:print' '*a+`' `'[a==n]*(3*n-a+~a)`;d-=1;a-=d/n+1
```
[Try it online!](https://tio.run/##BcFLCoAgEADQfadw5w8Jq1U2J4nAAQOFmCSMaNPVp/fq2/JJAzNCAoJC9W5KO989uRy7wAVorlehJoU0aKMUUa4IQJtRoyGH9kMdQ3LgAzpIPVnPPP0 "Python 2 – Try It Online")
If mixing output characters is OK.
[Answer]
# Powershell, 91 bytes
```
param($n)($s=' '*--$n+'#'*$n+'#')
--$n..0+,0*$n+0..$n|%{' '*$_+"#$(' '*(3*$n-2*$_+2))#"}
$s
```
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), ~~107~~ 97 bytes
```
param($n)($z=$n-1)..1+,0*$n+1..$z|%{" "*$_+"#"+($x=" "*($z-$_))+(" ","#")[!($_-$z)]*($n-2)+"$x#"}
```
[Try it online!](https://tio.run/##FcpBCoMwEEbhq9TxL8w4JjSlW09SJLgQXNhU7KKS6tmncfn43vL@jutnGufZbBnW4cVIwsgdkgvifdD21iBp8B55v/7oQg2iUk3K2Lozy@0QRZRLtUXkWTGiQ5a@YHJ3UcJW02Fmjz8 "PowerShell – Try It Online")
If there was a cheap way to reverse the first half, this answer would feel a lot better. It builds the left half, then the core (which is either x `#'s` or spaces), then mirrors the left's logic to make the right. Fun fact, you don't need to copy over trailing white-space.
Unrolled and explained:
```
param($n)
($z=$n-1)..1 + ,0*$n + 1..$z |%{  #Range that repeats 0 n times in the middle
" "*$_ + "#" +($x=" "*($z-$_)) +  #Left side
(" ","#")[!($_-$z)]*($n-2) +      #Core that swaps when it's the first or last row
"$x#"}                            #Right side which is left but backwards
```
[Answer]
# [APL (Dyalog Unicode)](https://www.dyalog.com/), 46 [bytes](https://codegolf.meta.stackexchange.com/a/9429/43319 "When can APL characters be counted as 1 byte each?")[SBCS](https://github.com/abrudz/SBCS ".dyalog files using a single byte character set")
```
(' '@~5 6∊⍨1⊥⊢∘,)⌺3 3⊢<(⍉⌽⌊⊢)⍣2∘(∘.+⍨∘⍳¯2+3×⊢)
```
This solution was provided by Adám - thanks! 
[Try it online!](https://tio.run/##SyzI0U2pTMzJT///X0NdQd2hzlTB7FFH16PeFYaPupY@6lr0qGOGjuajnl3GCsZAno3Go97ORz17H/V0AXmaj3oXGwEVaACxnjZQD5B@1Lv50HojbePD00EK/qc9apvwqLfvUd9UT/9HXc2H1hs/apsI5AUHOQPJEA/P4P9pCkZc6roKQKjOlaZgjMQ2AQA "APL (Dyalog Unicode) – Try It Online")
## My (almost) original solution:
# [APL (Dyalog Unicode)](https://www.dyalog.com/), 61 [bytes](https://codegolf.meta.stackexchange.com/a/9429/43319 "When can APL characters be counted as 1 byte each?")[SBCS](https://github.com/abrudz/SBCS ".dyalog files using a single byte character set")
```
(((⊃∘' #'¨1+5∘=+6∘=)⊢)1⊥⊢∘,)⌺3 3⊢<(((⊖⌊⊢)⌽⌊⊢)(∘.+⍨(⍳¯2+3×⊢)))
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT9dNzkksLs5M/v8/7VHbBA0NjUddzY86ZqgrKKsfWmGobQpk22qbgUjNR12LNA0fdS0F0kC@juajnl3GCsZAng1Y27RHPV0gJY969kJZGkBletqPeldoPOrdfGi9kbbx4ekgcU1NoG0KRlzqugpAqM6VpmCMxDYBAA "APL (Dyalog Classic) – Try It Online")
Thanks to Adám for his help!
The idea is to find the "diamond" that lies partly in the square and apply an edge-detect filter to "outline" the octagone.
[Answer]
# [C (clang)](http://clang.llvm.org/), `-DP=printf(` `-DF=for(i` ~~+ 179 = 199~~ 180 bytes
```
i;*m="%*s%*s\n";g(n){P"%*s",n,H;F;--i;)P H;P"\n");}f(n){g(n);F;--i;)P m,i,(H,3*n-i+~i,H;F-2;i--;)P"#%*s\n",3*n-3,H;F;--i;)P m,n-i,(H,n+i+i-1,H;g(n);}
```
[Try it online!](https://tio.run/##TYzBCoMwEETv/QqJFBLNHqrtacmtSI5@QC8iRBZ0W7Q3sZ/edGMPLSzDsPNmeujHjocYCYvJqWOxyN1Y4aDZrG16KMvWY4MAhKbNPLZKAINbSEjifuFkyWpv64KByhelHlRIABKq/Du9p/X/5GQFTz0uqSQ4SbbPbpH4mU0dsTbrIejKoGi963nXS4LefRi7YYlwbd1jlkrQ4r1TuTJiGhfusybHHw "C (clang) – Try It Online")
Ungolfed:
```
f(n){
	int i;
	printf("%*d",n,0);
	for(i=0;i<n-1;i++){
		printf("0");
	}
	printf("\n");
	for(i=1;i<n;i++){
		printf("%*d%*d\n",n-i,0,n+i+i-1,0);
	}
	for(i=0;i<n-2;i++){
		printf("0%*d\n",n+n+n-3,0);
	}
	for(i=n-1;i>0;i--){
		printf("%*d%*d\n",n-i,0,n+i+i-1,0);
	}
	printf("%*d",n,0);
	for(i=0;i<n-1;i++){
		printf("0");
	}
}
```
-19 bytes thanks to @ceilingcat
[Answer]
# [Python 2](https://docs.python.org/2/), 130 bytes
```
def f(n):
 a=[' '*~-n+n*'#']
 b=[' '*(n-i-2)+'#'+' '*(n+2*i) +'#'for i in range(n-2)]
 return a+b+['#%*s'%(3*n-3,'#')]*n+b[::-1]+a
```
[Try it online!](https://tio.run/##PY7LCoMwEEX3fsWASB5jFo10E@iXSBaRmnZARol20U1/PU2wdHnPfXC39/Fc2eZ8nyNEyco1EG6jAKE/hpG1aIVvYDqRZEPGKiwQT41Wk4IK4pqAgBhS4MdcklaVYpqPV2IIOOEo2k7vopODZjP0paK8ZpxG58zFY8j/BdsP/bUc2RLxAdRAdZbqREnK/fiSvw "Python 2 – Try It Online")
On mobile, so not incredibly golfed.
[Answer]
## Batch, 260 bytes
```
@echo off
set s=
for /l %%i in (1,1,%1)do call set s= %%s%%
echo %s% %s: =#%
call:c %1,-1,3
for /l %%i in (1,1,%1)do echo   #%s:~2%%s%%s:~2%#
call:c 3,1,%1
echo %s% %s: =#%
exit/b
:c
for /l %%i in (%*)do call echo %%s:~,%%i%%#%%s:~%%i%%%s%%%s:~%%i%%#
```
Outputs two leading spaces on each line. Explanation: Batch has no string repetition operator, limited string slicing capability and requires separate statements to perform arithmetic. It was therefore golfiest to make up a string of the input length in spaces (Batch can at least translate these to `#`s for the top and bottom lines) and then slice from or to a specific position ranging from 3 to the length to generate the diagonals (this is what the last line of the script achieves).
[Answer]
# [Ruby](https://www.ruby-lang.org/), 96 bytes
```
->n{[*(n-=2).step(z=n*3+2,2),*[z]*n,*z.step(n,-2)].map{|x|([?#]*2*('# '[x<=>n]*x)).center(z+2)}}
```
[Try it online!](https://tio.run/##NcuxDoMgEADQXzFx8O4EhmvSqdgPIQza4NYLUUwoyrfToen88rZj@bTVNj3J6QhEW0azpxChWKHbyIpRkSueRFH5iSjN6M17jueVL3DP3hMTDH03uPywk3jKiOYVJIUNyshYawM25o7/FI@0d6vLvrYv "Ruby – Try It Online")
Not very golfed yet. Might golf if I find the time.
[Answer]
# [Red](http://www.red-lang.org), 171 bytes
```
func[n][c:(a: n - 1)* 2 + n
b: collect[loop c[keep pad/left copy"^/"c + 1]]s: 1x1 s/1: n
foreach i[1x0 1 0x1 -1x1 -1x0 -1 0x-1 1x-1][loop a[b/(s/2)/(s/1): #"#"s: s + i]]b]
```
[Try it online!](https://tio.run/##PYxBCoMwEEX3OcVHN9oicWy7yTG6DSloTKhUkqAW7OntFKmbx2P@8CbXb3fXayO82vw7WB2MtqpoFQIqUHlCgzOC6BRsHEdnFz3GmGD1y7mE1PZydH7hMX2yh8wsf5MxswKthFkSh4SPk2vtE4OmtQah5qmiHTWDDwximL3e6k4Ws2zKH6lUyLM84@bM9cGYzmxpGsICj0b87XLY9bCb2L4 "Red – Try It Online")
## Explanation:
```
Red[]
f: func [ n ] [
    a: n - 1                                         ; size - 1
    c: a * 2 + n                                     ; total size of widht / height 
    b: collect [                                     ; create a block
        loop c [                                     ; composed of size - 1 rows
            keep pad/left copy "^/" c + 1            ; of empty lines of size c (and a newline)
        ]
    ]
    s: a * 1x0 + 1                                   ; starting coordinate
    foreach i [ 1x0 1 0x1 -1x1 -1x0 -1 0x-1 1x-1 ] [ ; for each offset for the 8 directions
        loop a [                                     ; repeat n - 1 times  
            b/(s/2)/(s/1): #"#"                      ; set the array at current coordinate to "#"
            s: s + i                                 ; next coordinate
        ]        
    ]
    b                                                ; return the block 
]
```
[Answer]
# **Perl 5, ~~201~~ ~~197~~ ~~188~~ ~~187~~ 186 bytes:**
```
$a=<>;$b=3*$a-4;$c='$"x($e-$_)."#".$"x$f."#\n"';$e=($b-$a)/2+1;$d=$"x$e."#"x$a.$/;$f=$a;print$d,(map{(eval$c,$f+=2)[0]}1..$a-2),("#".$"x$b."#\n")x$a,(map{$f-=2;eval$c}reverse 1..$a-2),$d
```
[Try it online!](https://tio.run/##PY3hCoIwFIVfJdYBt3QzV/5a60UqYuodBCayQoTw2Zci9e8e7vnO11Noyxjh7OlsUNnDDk4eDWqbgI0cJHEXim2ZmiP8fF07lhiQ5agknMh1Whg0dnnTUhzhFHIDb@FMHx7dG03Gn67/cBpcizqDT60Wl/1tKpSadVpk/GeoVoOYV1YIXlptVnIKNFB40ebPoYmx/AI "Perl 5 – Try It Online")
Reads the size of the octagon from first line of `STDIN`.
[Answer]
# **Perl 5, 176 bytes**
```
$f=$a=<>;$b=3*$a-4;$c='$"x($e-$_)."#".$"x$f."#\n"';$e=$a-1;$d=$"x$e."#"x$a.$/;print$d,(map{(eval$c,$f+=2)[0]}1..$a-2),("#".$"x$b."#\n")x$a,(map{$f-=2;eval$c}reverse 1..$a-2),$d
```
Based on Nathan Mills' answer above (which I have insufficient rep to comment on!).
`$e` can be simplified to `$a-1` saving 6 bytes;
`$f` can be chain assigned; saving two bytes;
Not sure where the other two come from!
While `$e` can be replaced with `$a-1` in the two places it occurs, the extra brackets needed means this only breaks even.
**Ungolfed:**
```
$f = $a = <>;
$b = 3 * $a - 4;
$c = '$"x($e-$_)."#".$"x$f."#\n"';
$e = $a - 1;
$d = $" x $e . "#" x $a . $/;
print $d, ( map { ( eval $c, $f += 2 )[0] } 1 .. $a - 2 ),
  ( "#" . $" x $b . "#\n" ) x $a,
  ( map { $f -= 2; eval $c } reverse 1 .. $a - 2 ), $d
```
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), ~~76~~ 73 bytes
*-3 bytes thanks to Jo King*
```
{(' 'x$_-1~\*x$_,{S/.\S(.)+/* {' 'x$0}*/}...*)[^$_,$_ xx$_-2,[R,] ^$_;*]}
```
[Try it online!](https://tio.run/##K0gtyjH7n1upoJamYPu/WkNdQb1CJV7XsC5GC0jrVAfr68UEa@hpautrKVSDJQ1qtfRr9fT0tDSj44AqVOIVKkA6jHSig3RiFYBC1lqxtf@LEysV0jRU4jX1svIz8zSUYvKUNBXS8osUjPT0TK3/AwA "Perl 6 – Try It Online")
Returns a list of lines.
[Answer]
# [C (gcc)](https://gcc.gnu.org/), ~~158~~ ~~153~~ 150 bytes
* Saved ~~five~~ eight bytes thanks to [ceilingcat](https://codegolf.stackexchange.com/users/52904/ceilingcat).
```
O,c,t,g;o(n){for(O=2*~-n,t=c=O+n;t--;puts(""))for(g=c;g--;)putchar(33-(!t|t>c-2?g<n-1|g>O:t<n-1|t>O?t+O-g&&t-O-g&&~c+g+t+n+n&&c-g-t+n-3+n:g&&g<c-1));}
```
[Try it online!](https://tio.run/##RY6xEoIwEES/RQom8XIFUGkI9GnyDczNeFp4OHhWIr@OAQur3Xn7iiVkonVNjpw69qMR@76Mk0mhPi4oTgOFBOIV0T9e@jRFYe0mcCDPGdpM6TpMpmnQHHTWjrDuuRWsZu7SWfemXeoVEnJZKu6xEDAoCEhZEjLmig3IOU/cElbW@s96H25i4u9RDLWP7en/YjQRYLO@ "C (gcc) – Try It Online")
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal) `RM`, 4 bytes
```
S7ø∧
```
[Try it Online!](https://vyxal.pythonanywhere.com/#WyJSTSIsIiIsIlM3w7jiiKciLCIiLCI1Il0=)
new canvas builtin go brr
[Answer]
# [Python 3](https://docs.python.org/3/), 224 bytes
```
n=int(input())
z=" "*(n-1)+"#"*n+" "*(n-1)
print(z)
for i in range(n-2):print(" "*(n-i-2)+"#"+" "*(i*2+n)+"#")
print((("#"+" "*(n*3-4)+"#\n")*n)[:-1])
for i in range(n-3,-1,-1):print(" "*(n-i-2)+"#"+" "*(i*2+n)+"#")
print(z)
```
[Try it online!](https://tio.run/##lY27DgIhEEV7voJgw4AULCYmm@yXqIWFj2nuEoKF/DyCq1vZmExz59xHfOb7jFArJkbWjPjImkiUSUllNJwnqzbKwK5axNSthcR1TpIlQ6YzbpcGBxoX@DFz@/T4EmYzWLz1t0PrFcIEt@vwCEUGdBidP/2YCFvn2/05VKjW/Qs "Python 3 – Try It Online")
[Answer]
# Perl 5, ~~170~~ ~~168~~ 166 bytes
```
$a=<>-1;$\="#\n";print$x=$_=$"x$a."#"x$a;if(s/^( *)  #*/$1 #  $1 /){print}while (s/ #/#  /){print}$z=$_;for(1..$a){print$_=$z}while(s/#  (\s{$a})/ #$1/){print}print$x
```
This works by the magic of regex. The "if" is only needed to deal with the pathological case of n=2, which otherwise outputs something like:
```
 ##
 ##
#  #
 ##
```
probably this can be coded away.
I think there may be a lot more to gain by creating a string up to the mid-point then reversing it. Of course we then need to insert/delete an extra space if n is odd (or use thin-space :p). 
**Ungolfed**
```
$a = <> -1;                          # Subtracting one is very useful! 
$\ = "#\n";                          # Every line ends with a '#' let perl provide.  
$x=$_ = " " x $a. "#" x $a;          # The horiz line (one short)  
print;                               # print it plus the extra #
if(s/^( *)  #*/$1 #  $1 /){print}    # create a hole and remove a leading space(if n=2 this fails)
while (s/ #/#  /){                   # make the hole bigger      
    print;                           # and print (with a trailing #)
}
$z=$_;                               # store $_ for later use
for (1 .. $a) {                      # nice that we don't have to do 2..$a but not golf-nice  
  $_ =$z;                            # restore $_ (we could use $z but since we have
  print;                             # to restore somewhere, doing  it here saves us bytes)
}
while (s/#  (\s{$a})/ #$1/){         # now move the # to the right and reduce the trailing spaces  
  print;
}
print $x;                            # and finish...
```
I think this can probably be golfed a bit more, quite apart from significant changes like pushing onto `$@` and printing that at the end.
[Golfed spaces around `..` and moved print before assigns in two cases, saving on semicolons.]
[Answer]
# J, ~~59~~ ~~45~~ 41 bytes
```
h=.|.,],~,:@{.#~_2+#
' #'{~h@|.@|:@h@=@i.
```
[Try it online!](https://tio.run/##y/r/P8NWr0ZPJ1anTsfKoVpPuS7eSFuZK81WT11BWb26LsOhRs@hxsohw8HWIVPvP1dqcka@QpqCEYxhDGOYwBim/wE "J – Try It Online")
Will add explanation tonight.
[Answer]
# Perl 5, 98 bytes
```
$_=2x$_.1x$_.$/;s/2//;s/.$/ #/,y/1/ /while$a.=$_,$b=$_.$b,s/2[#1]/# /;$_=$a.$_ x("@F"-2).$b;y/2/ /
```
[TIO](https://tio.run/##FYxBCsIwEEX3OUVoZqGQdki0qyHgykuIhAQKFqoNVrC5vONk8/jwH69M72XkZ4VEgkwMMfgd4uAaAGlDj42ytUFb0aHG72NeJkhDgGghh2ZmK@bNuDsajSQVuSHq/dBdrl3vj2JQlZZG5pNSZ6X8by2feX1t3Jf0Bw)
]