# 16-bit binary grid

Given any unsigned 16 bit integer, convert its decimal form (i.e., base-10) number into a 4x4 ASCII grid of its bits, with the most-significant bit (MSB) at the top left, least-significant bit (LSB) at bottom right, read across and then down (like English text).

## Examples

### Input: 4242

+---+---+---+---+
|   |   |   | # |
+---+---+---+---+
|   |   |   |   |
+---+---+---+---+
| # |   |   | # |
+---+---+---+---+
|   |   | # |   |
+---+---+---+---+


### Input: 33825

+---+---+---+---+
| # |   |   |   |
+---+---+---+---+
|   | # |   |   |
+---+---+---+---+
|   |   | # |   |
+---+---+---+---+
|   |   |   | # |
+---+---+---+---+


## Specific Requirements

1. Input must be in decimal (base-10), however you may convert to binary any way you wish (including using language built-ins, if available).

2. Output table format must match exactly. This means you must use the specific ASCII characters (-, +, and |) for the table grid lines as shown, each cell's interior is 3 characters, and true bits are represented by # while false is represented by a space ().

3. Leading or trailing whitespace is not permitted. Final newline is required.

4. Bit order must match the examples as described.

## Allowances

1. Input must be a base-10 number on the command line, standard input, or user input, but must not be hard-coded into your source code.

May the clearest shortest code win! :-)

• Related Sep 18, 2015 at 16:38
• The first sentence sounds confusing to me, where it says "convert its decimal form". Based on the rest of the post and the example, it looks like the input is given in decimal form, but you have to convert the binary form of the value into a grid. Sep 18, 2015 at 16:44
• @RetoKoradi you are essentially correct, but the question does require you to convert a decimal number into a binary grid. There is no explicit requirement to ever work with a binary number, only a likely implementation detail. Sep 18, 2015 at 17:53
• Does writing a function with the base-10 number as the function argument count as user input? Sep 18, 2015 at 18:12
• Since you say that the given number is an "unsigned 16 bit integer", it is by definition in binary form. When I first read this, it actually sounded like the input would be given in binary form. It all becomes clear towards the end. But at least for me, the first paragraph really doesn't capture the problem at all. Sep 18, 2015 at 18:20

# J, 26 bytes

('   ';' # '){~4 4$_16{.#:  An anonymous verb. Thankfully, J is very good at drawing boxes. Let's try it out:  f =. (' ';' # '){~4 4$_16{.#:
f 4242
+---+---+---+---+
|   |   |   | # |
+---+---+---+---+
|   |   |   |   |
+---+---+---+---+
| # |   |   | # |
+---+---+---+---+
|   |   | # |   |
+---+---+---+---+


As some commenters have mentioned, the way J draws boxes is system-dependent: on some platforms, this code will work under the default settings, but on others, the boxes will be drawn using Unicode line drawing characters. (The commands 9!:6 and 9!:7 allow you to query and set the characters to draw boxed values with, respectively.)

• Do you (or anyone else) know if there's a consensus on the box drawing command for golf scoring, then? I personally think the assumption with code golf is that solutions work on a majority of systems that the solution's language runs on, right? What would a solution look like that outputs the correct boxes on all (or almost all) J installations? I really like your solution, by the way! My brain is still working its way through, which is exactly what I like about code golf. Sep 18, 2015 at 20:30
• @type_outcast We don't require portability for code golf challenges. As long as it works with some implemenation on one platform, it's valid. Sep 18, 2015 at 20:45
• Thanks for the response @Dennis. I'm happy my presumption was incorrect, then, because I (still) really like Mauris' solution! :-) Sep 18, 2015 at 20:57

# JavaScript (ES6), 102

... or 96 using return instead of console.log.

Test running the snippet below in an EcmaScript 6 compliant browser.

f=n=>{for(o=h=
+---+---+---+---+
,z=16;z--;n/=2)o=(z&3?'':h+'|')+ ${' #'[n&1]} |+o;console.log(o)} // TEST console.log=x=>O.innerHTML=x+O.innerHTML function test(n) { f(n); console.log(n); } <input id=I value=4680><button onclick='test(+I.value)'>-></button> <pre id=O></pre> • Is "JavaScripy" some strange javascript/python mashup? ;-) Sep 18, 2015 at 20:52 • @DigitalTrauma of course. But as the world is not ready (tvtropes.org/pmwiki/pmwiki.php/Main/TheWorldIsNotReady) for this new evolution, I'll revert to JavaScript Sep 18, 2015 at 21:07 • Cool, this works on Edge! Sep 20, 2015 at 5:36 • Must... not... click... tvtropes... – RK. Sep 21, 2015 at 18:22 # Befunge-93, 196 218 bytes &00p12*v>>4>"---+",v v < v*:*:*:< | :-1,,,< # >:*2/10p^ >"+",25*,10g| > #v^#$< @
25*,^  >4" |",,v ,*<>
v>"#",00g10g-00p 10g
|-1g01g00     <>48^
v>" ",10g
>2/10p>"| ",,1-:#^_$>^  ### To run the program... 1. Go to the online interpreter. 2. Paste this code in the big text box. 3. Click Show. 4. Input the desired number in the Input box. 5. Click Run. (Or change Slow to something like 5 milliseconds and then click Show.) 6. Ta-da! Output for 4242: +---+---+---+---+ | | | | # | +---+---+---+---+ | | | | | +---+---+---+---+ | # | | | # | +---+---+---+---+ | | | # | | +---+---+---+---+  Output for 33825: +---+---+---+---+ | # | | | | +---+---+---+---+ | | # | | | +---+---+---+---+ | | | # | | +---+---+---+---+ | | | | # | +---+---+---+---+  ## Explanation Oh goodness, what have I got myself into? Well, here goes! (Irrelevant code is replaced with .s.) ### Part 1: Get input (store in 0,0) and calculate 32768 (store in 1,0). &00p12*v> v*:*:*:< >:*2/10p^  ### Part 2: Print out "+---+---+---+---". >4>"---+",v | :-1,,,<  ### Part 3: Print "+" and a newline and check to see if (1,0) is 0 (i.e. we're done). If so, terminate. Otherwise, continue.  ........... v < | ....... # >"+",25*,10g| v.#$< @
>4" |",,v ...


### Part 4: Get binary digits of input, updating (0,0) and (1,0) as we go along. Print the right things. I take advantage of Befunge's wrap-around behavior.

 .....  >4" |",,v ,*<.
v>"#",00g10g-00p 10g
|-1g01g00     <>48^
v>" ",10g
>2/10p>"| ",,1-:#^_...


### Part 5: Print a newline and go back to the part that prints "+---+---+---+---+". Wrap-around trick is used.

     > #.^.         .. .
25*,^  ......... ...>
................ ...
.........      .....
........
.................._$>^  ### Ta-da! # Julia, 156 143 bytes n->(p=println;l="+"*"---+"^4;for i=1:4 p(l,"\n| ",join([j>"0"?"#":" "for j=reshape(split(lpad(bin(n),16,0),""),4,4)[:,i]]," | ")," |")end;p(l))  Ungolfed: function f(n::Int) # Convert the input to binary, padded to 16 digits b = lpad(bin(n), 16, 0) # Split b into a 4x4 matrix m = reshape(split(b, ""), 4, 4) # Store the line separator for brevity l = "+" * "---+"^4 # Print each column of the matrix as a row for i = 1:4 println(l, "\n| ", join([j > "0" ? "#" : " " for j = m[:,i]], " | "), " |") end # Print the bottom of the table println(l) end  Try it online # Python 2, 157153151 146 bytes J=''.join;R='+---'*4;i=format(input(),'016b') print J(R+'+\n|'+J(' '+('#'if int(l)else' ')+' |'for l in i[n*4:-~n*4])+'\n'for n in range(4)),R+'+'  Thanks to Morgan Thrapp for saving 4 bytes, and to Jonathan Frech for saving 5. ## Usage $ python test.py
33825
+---+---+---+---+
| # |   |   |   |
+---+---+---+---+
|   | # |   |   |
+---+---+---+---+
|   |   | # |   |
+---+---+---+---+
|   |   |   | # |
+---+---+---+---+

• You can save two bytes if you pull '+---'*4 into a variable and two more if you do j=''.join Sep 18, 2015 at 19:50
• No problem! I was actually working on a very similar solution. Sep 18, 2015 at 19:57
• @downvoter Care to explain? Sep 10, 2017 at 21:26
• Since you do not use Python 3, you can replace int(input()) with input() and save five bytes. Sep 10, 2017 at 23:53

# GNU sed + dc, 116

Score includes +1 for -r flags to sed:

s/.*/dc -e2o&p/e
:
s/^.{,15}$/0&/;t s/./| & /g s/.{16}/\n+---+---+---+---+\n&|/g y/01/ #/ s/\n([-+]+)(.*)/\1\2\n\1/  Test output: $ { echo 4242 ; echo 33825 ; } | sed -rf 16bitgrid.sed
+---+---+---+---+
|   |   |   | # |
+---+---+---+---+
|   |   |   |   |
+---+---+---+---+
| # |   |   | # |
+---+---+---+---+
|   |   | # |   |
+---+---+---+---+
+---+---+---+---+
| # |   |   |   |
+---+---+---+---+
|   | # |   |   |
+---+---+---+---+
|   |   | # |   |
+---+---+---+---+
|   |   |   | # |
+---+---+---+---+
$ Alternatively: # Pure sed, 146 You might think it's cheating to use sed's GNU extension to eval a dc command. In that case, we can do this a little differently, according to this meta-answer. Of course the question clearly states that input must be in base 10, but here I'm attempting to claim that we can override that for sed answers and use unary (base 1) instead. : s/11/</g s/<([ #]*)$/< \1/
s/1/#/
y/</1/
t
:a
s/^.{,15}$/0&/;ta s/./| & /g s/.{16}/\n+---+---+---+---+\n&|/g y/01/ #/ s/\n([-+]+)(.*)/\1\2\n\1/  ### Test output Using printf to generate the necessary unary string: $ printf "%33825s" | tr ' ' 1 | sed -rf 16bitgrid.sed
+---+---+---+---+
| # |   |   |   |
+---+---+---+---+
|   | # |   |   |
+---+---+---+---+
|   |   | # |   |
+---+---+---+---+
|   |   |   | # |
+---+---+---+---+
$ • Nice one. This looks somewhat similar to the Perl solution I came up with as a (private) proof of concept while fine-tuning the question. Sep 18, 2015 at 20:59 • @type_outcast BTW its perfectly OK to post your own solution as an answer :) Sep 18, 2015 at 21:04 • I know :-) I didn't spend much time golfing it, as I was more focused on putting up a good question, but I may yet revisit it and post it if I can golf it into something at least halfway respectable. At the moment I'm having too much fun grokking everyone else's answers. Sep 18, 2015 at 21:07 # Ruby, 118 114 b="%016b"%gets l=?++"---+"*4 1.upto(16){|i|puts l if i%4==1 print"| #{b[i-1]==?0?' ':?#} " puts ?|if i%4<1} puts l  thanks for @w0lf for saving some characters. • You can save some bytes if you write literal characters using the ? notation (ex: ?| instead of '|'). This works for everything except space. Sep 19, 2015 at 12:03 • @w0lf I have found that ?\s works for space, however it is not actualy helpful here. Sep 20, 2015 at 17:41 # C++11, 193191190176 172 bytes My first solution on codegolf ever, so do not blame me. #include<iostream> int n,j,i=65536;int main(){std::cin>>n;for(;j<9;){for(int k:{0,0,0,0})if(j%2)printf("| %s",n&(i/=2)?"# ":" ");else printf("+---");puts(j++%2?"|":"+");}}  Ungolfed #include <iostream> int n, i = 65536, j; int main() { std::cin >> n; for (; j < 9;) { for(int k:{0,0,0,0}) { if (j % 2) { printf("| %s", n & (i /= 2) ? "# " : " "); } else { printf("+---"); } } puts(j++ % 2 ? "|" : "+"); } }  Previous version #include <iostream> using namespace std; int n, i = 65536, j; int main() { cin >> n; for (; j < 9;) { for(int k:{0,0,0,0}) { if (j % 2) { cout << "| " << (n & (i /= 2) ? "# " : " "); } else { cout << "+---"; } } cout << (j++ % 2 ? "|\n" : "+\n"); } }  • Hint: 0x10000 is 65536, having '0x' prefix, hex is always longer than decimal Sep 18, 2015 at 20:27 • Hint 2: youd should avoid using namespace std in production code. And it's not useful here too. Sep 18, 2015 at 20:29 • @edc65 dec->hex good idea, I always thought of hex having shorter representation, but forget about 0x. using namespace std saves few bytes, because I do not have to prefix cout and cin with std::. Even using just using std::cout; wont help. Sep 18, 2015 at 20:31 • Hey Zereges. You can remove the space between the include and the library.. and remove the return type for the main function. Sep 18, 2015 at 20:39 • C++ does not support auto int. Sep 18, 2015 at 20:40 # Pyth, 37 bytes Jj*3\-*5\+JVc4_m@" #".>Qd16jd.i*5\|NJ  Try it online: Demonstration or Test Suite ### Explanation: Jj*3\-*5\+J *3\- the string "---" *5\+ the string "+++++" j join second by first string: "+---+---+---+---+" J save in J J print J Vc4_m@" #".>Qd16jd.i*5\|NJ m 16 map each d in [0, 1, ..., 15] to: .>Qd input number Q shifted to the right by d @" #" and take the ^th char in " #" (modulo 2) _ reverse this list of chars c4 split into 4 groups V for each group N in ^: *5\| the string "|||||" .i N interleave ^ with N jd join chars with spaces and print J print J  # CJam, 43 41 bytes '+5*'-3**N+ri2bG0e[4/{" #"f='|5*.\S*N2$}/


Definitely golfable, but it's a start I guess. Generates the top row, then for each 4 bits it creates an even row and copies the previous odd row.

# Python 2, 122121 120 bytes

n=bin(4**8+input())[3:]
i=0
exec"print'| %s |'%' | '.join(' #'[x>'0']for x in n[:4])*i or'+---'*4+'+';n=n[4*i:];i^=1;"*9


-1 byte thanks to @xnor's neat 4**8+ trick. The main printing is done by looping 9 times, selecting the appropriate row for odd/even.

• I think that bin(4**8+input())[3:] saves a byte over format
– xnor
Sep 19, 2015 at 8:49
• @xnor Oh, that's neat :) Sep 19, 2015 at 8:55

## Python 2, 94

n=input()
s=();exec"s=(' #'[n%2],)+s;n/=2;"*16
a='+---'*4+'+\n'
print(a+'| %s '*4+'|\n')*4%s+a


The idea is to take the pattern

+---+---+---+---+
| _ | _ | _ | _ |
+---+---+---+---+
| _ | _ | _ | _ |
+---+---+---+---+
| _ | _ | _ | _ |
+---+---+---+---+
| _ | _ | _ | _ |
+---+---+---+---+


except with %s in place of blanks and perform tuple substitution. The tuple looks like

('#', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', '#')


It is created by taking taking off digits from the input in binary and adding the corresponding symbol to the front of the tuple. An expression with explicit tuple gave equal length.

%tuple(' #'[c>'0']for c in bin(input()+4**8)[3:])


Thanks to Sp3000 for 2 bytes.

# PowerShell, 203188 182 Bytes

param($a)$l="+---+---+---+---+";$l;$b=([int64][convert]::ToString($a,2)).ToString(@(,"0"*16)-join'');@(1..16|%{if($b[$_-1]-eq'1'){"| # "}else{"| "};if($_%4-eq0){"|n$ln"}})-join''  Edit - saved 15 bytes by changing the order that | are drawn, so we can dump the .TrimEnd("|") on the output and instead convert the for-loop into a subcode block that produces an array Edit2 - saved another 6 bytes by eliminating need for saving into the $o variable and just outputting with -join'' directly.

Ooooooooof.

Drawing in PowerShell is hard. Working with binary digits in PowerShell is hard.

Uses built-ins to [convert] the input integer to a string representation in binary, then re-cast back to an [int64] so we can re-call .ToString() in order to prepend/pad the appropriate number of zeroes. (Note that creating an array of strings and joining them @(,"0"*16)-join'' is 1 character shorter than the literal string "0000000000000000")

Then, take a simple for-loop 1..16|%{...} checking each digit to build up our output array, then finally -join'' that back together.

• This seems to have stopped working, but by golfing it a bit more, I can get 197 with the correct result: i=>,${("0".repeat(16)+i.toString(2)).slice(-16).split.map((v,l,a)=>l%4?"":"| "+a.slice(l,l+4).map(v=>' #'[v]).join | +" |").filter(v=>v).join,},.replace(/,/g,<line break>+---+---+---+---+<line break>).slice(1) Sep 18, 2015 at 22:34 • ("0".repeat(16)+i.toString(2)).slice(-16) --> (65536|i).toString(2).slice(1) Sep 19, 2015 at 0:36 • Keeping your exact logic, this can be golfed to 169, see jsfiddle.net/76fp7aw6 Sep 19, 2015 at 13:40 # CJam, 62 bytes "+---| "4/{4*_c+N+}%4*_0=]sqi2bG0e[ee{~{_9*\4%5*-K+'#t0}&;}/  # Pyth, 50 bytes j.i*5]<3*5"+---"ms.i*5\|dc4mj@" #"qd\1*2\ .[Z16.BQ  Explanation will have to wait until another time, I'm posting this on my phone! # Ruby, 102 n=gets.to_i print j="+---"*4+"+ " 19.downto(0){|i|print i%5>0?"| #{((n>>i*4/5)%2*3+32).chr} ":"| "+j}  Algorithm Print a horizontal divider Loop 20 times (19..0) If loop number does not divide by 5, convert into a number in the range 16..0 by multiplying by 4/5. Print a space (ascii 32) or # (ascii 32+3=35) preceded by |  and followed by a space. If loop number divides by 5, print a terminating |, newline, and a horizontal divider identical to the first. # Perl, 103 bytes $_=(($l='+---'x4 .'+ ').'| x 'x4 .'| ')x4 .$l;@n=(sprintf'%016b',<>)=~/./g;s/x/$n[$x++]?'#':$"/eg;print  Lots of string repetition to make a grid of xs, convert the input to binary and then s/// the xs to # or $" () depending on the flag at the specified position ($x). # PHP, 159 bytes bingrid16.php: <?$r=10;while(--$r){if($r%2){echo str_repeat('+---',4).'+';}else{$c=9;echo'|';while(--$c){echo' '.($c%2?'|':($argv[1]&pow(2,$r*2+$c/2-5)?'#':' '));}}echo"\n";}


Usage:

php bingrid16.php 4242


Nothing fancy, just brute-forced the rendering.

I tried another angle using arrays instead of loops, but it was longer at 224 bytes:

<?=implode(array_map(function($r)use($argv){return($r%2?str_repeat('+---',4).'+':'|'.implode(array_map(function($c)use($r,$argv){return' '.($c%2?'|':($argv[1]&pow(2,$r*2+$c/2-5)?'#':' '));},range(8,1))))."\n";},range(9,1)));


# Perl 5, 85 84 bytes

84 83 bytes of code + -p flag

-1 byte after Dom reminded me to use a newline

say$\='+'."---+"x4," | ",map y/01/ #/r.' | ',/./g for(sprintf"%016b",$_)=~/..../g}{


Try it online!

• Nice, much better approach than mine! A literal newline will save you an extra byte over $/ too! Sep 11, 2017 at 12:16 # Vyxalj, 47 bytes b:L16-(0p)4ẇƛƛ‛ #$i| % $%;ṅ\|+;\+:3-4*pw5ẋf$Y


Try it Online! A big mess

• You sure there isn't a flag that can be used here? Jun 14, 2021 at 6:24
• @lyxal True, forgot Jun 14, 2021 at 6:25

# Japt-R, 40 36 bytes

This'll need another pass once I'm properly caffeinated!

5Æ17î-³i+ÃíUs'#iS)ùG ®û3 i|ÃòG)cf ú|


Try it

5Æ17î-³i+ÃíUs'#iS)ùG ®û3 i|ÃòG)cf ú|     :Implicit input of integer U
5Æ                                       :Map the range [0,5)
17î                                    :  Repeat the following to length 17
-³                                  :    "-" repeated 3 times
i+                                :    Prepend a "+"
Ã                               :End map
í                              :Interleave with
Us                            :  U converted to a string in the following base
'#i                         :    "#" prepended with
S                        :    A space
)                       :  End base conversion
ù                      :  Left pad with spaces to length
G                     :    16
®                   :  Map each character
û3                 :    Centre pad with spaces to length 3
i|              :    Prepend a "|"
Ã             :  End map
òG           :  Partitions of length 16
)          :End interleave
c         :Flatten
f        :Filter out falsey elements (If the second array being interleaved is shorter than the first, it's padded with null)
ú|     :Left pad each with "|" to the length of the longest
:Implicit output joined with newlines


# Vyxal, 31 bytes

\+3-4*\|?b16∆Z\#*2↳ʁ+4ẇṠv"fǏvǏ⁋


Try it Online!

        ?                       # Input
b                      # To binary
16∆Z                  # Pad to length 16 with 0s
\#*               # That many #s, for each bit
2↳ʁ            # Pad to length 2 with spaces and mirror
\|            +           # Prepend | to each
4ẇṠ        # Divide into rows and stringify each
v"f     # Interleave with...
\+3-                            # "+---"
4*                          # Repeated four times
Ǐ    # Append the first line
vǏ  # For each line, append the firstt character
⁋ # Join the result by newlines

• Nice! Appreciate you de-golfing it for us mere mortals, not to mention coming back with another solution after so long. Nov 25, 2022 at 1:47

# c99 263 bytes

golfed:

main(int argc,char **argv){short i=atoi(argv[argc-1]);char *t="| # ", *f="|   ",*a[16],**p=a,*b="+---+---+---+---+\r\n";while(p<a+16){if((i|0x8000)==i)(*(p++))=t;else(*(p++))=f;i<<=1;}for(p=a;p<a+16;p+=4)printf("%s%s%s%s%s|\n",b,*p,p[1],p[2],p[3]);printf("%s",b);}


ungolfed:

main(int argc, char **argv)
{
short i=atoi(argv[argc -1]);
char *t ="| # ", *f="|   ",*a[16],**p=a,*b="+---+---+---+---+\r\n";

while (p<a+16)
{
if((i|32768)==i)
(*(p++))=t;
else
(*(p++))=f;

i<<=1;
}

for (p=a;p<a+16;p+=4)
printf("%s%s%s%s%s|\n",b,*p,p[1],p[2],p[3]);
printf("%s",b);
}


I just liked to present a bit shifting variant and felt this is the first time its appropriate (even its costing me some bytes, but C can't this challange in bytes even with a chance so I don't care) to use the argc/argv

# Ruby, 95

Nod to Mhmd for a concise String conversion, but I wanted to try using string methods instead of number methods.

->i{puts g='+---'*4+?+;("%016b"%i).scan(/.{4}/){puts$&.gsub(/./){"| #{$&<?1?' ':?#} "}+"|
"+g}}


# Ruby, 93

A slightly shorter version using only numeric operations.

->i{n=g='+---'*4+"+
";15.downto(0){|m|n+="| #{[' ',?#][1&i>>m]} "
n+="|
"+g if m%4<1}
puts n}


## C# 227 Bytes

Golfed:

class B{public static string G(short v){string s="",b=System.Convert.ToString(v,2).PadLeft(16,'0');for(int i=9;i>0;){s+=i--%2!=0?"+---+---+---+---+\n":"| "+b[i*2+1]+" | "+b[i*2]+" | "+b[i*2-1]+" | "+b[i*2-2]+" |\n";}return s;}}


Indention:

class B
{
public static string G(short v)
{
for(int i=9;i>0;)
s+=i--%2!=0?"+---+---+---+---+\n":"| "+b[i*2+1]+" | "+b[i*2]+" | "+b[i*2-1]+" | "+b[i*2-2]+" |\n";
return s;
}
}


First time I'm trying something like this, tips would be welcome!

• Firstly, I count 286 bytes and you can remove the indentation spaces.
– Blue
Sep 21, 2015 at 17:57
• How exactly do you count it? I've been going to the properties to see the file size there, but I'm not sure if that's the way to do it! Without indentation I've come down to 230 bytes! Sep 21, 2015 at 18:03
• Use something like mothereff.in/byte-counter, or if you're on linux, use the wc command
– Blue
Sep 21, 2015 at 18:21

# Python 3, 145 144 Bytes

Inline:

a="|";b="+"+"---+"*4+"\n";r=0,1,2,3;(lambda x:print(b+b.join(a+a.join(" %s "%'# '[x&2**(i+j*4)<1]for i in r)+a+"\n"for j in r)+b))(int(input()))


With newlines:

a="|"
b="+"+"---+"*4+"\n"
r=0,1,2,3
lambda x:print(b+b.join(a+a.join(" %s "%'# '[x&2**(i+j*4)<1]for i in r)+a+"\n"for j in r)+b)
x(int(input()))


Edit: Tanks @manatwork for saving 1 byte

• Based on gnibbler's tip, hardcoding r=0,1,2,3 is 1 character shorter than generating it with r=range(4). Sep 11, 2017 at 11:20

# x86-16 machine code, IBM PC DOS, 80 bytes

Binary:

00000000: b805 09ba 2801 cd21 fec8 741b be3e 01b1  ....(..!..t..>..
00000010: 04d1 e3c6 0420 7303 c604 2383 c604 e2f1  ..... s...#.....
00000020: ba3c 01cd 21eb dcc3 2b2d 2d2d 2b2d 2d2d  .<..!...+---+---
00000030: 2b2d 2d2d 2b2d 2d2d 2b0d 0a24 7c20 2020  +---+---+..$| 00000040: 7c20 2020 7c20 2020 7c20 2020 7c0d 0a24 | | | |..$


Listing:

B8 0905         MOV  AX, 0905H              ; AH = DOS write string, AL = row counter
ROW_LOOP:
BA 0128         MOV  DX, OFFSET SEP         ; show separator row
CD 21           INT  21H                    ; write to console
FE C8           DEC  AL                     ; displayed 5 separators?
74 1B           JZ   EXIT                   ; if so, exit
BE 013E         MOV  SI, OFFSET ROW+2       ; start SI at location of first bit in row
B1 04           MOV  CL, 4                  ; loop count 4
BIT_LOOP:
D1 E3           SHL  BX, 1                  ; shift MSb into CF
C6 04 20        MOV  BYTE PTR[SI], ' '      ; reset to space char
73 03           JNC  BIT_DONE               ; if not CF, leave as a space
C6 04 23        MOV  BYTE PTR[SI], '#'      ; otherwise change to a #
BIT_DONE:
83 C6 04        ADD  SI, 4                  ; increment index 4 bytes
E2 F1           LOOP BIT_LOOP               ; keep looping through bits
BA 013C         MOV  DX, OFFSET ROW         ; show bit column row
CD 21           INT  21H                    ; write to console
EB DC           JMP  ROW_LOOP               ; keep looping
EXIT:
SEP DB  '+---+---+---+---+',0DH,0AH,'$' ROW DB '| | | | |',0DH,0AH,'$'


Callable function, input in BX output to STDOUT.

Example test program:

# Kotlin, 192 bytes

{val v=it.toString(2).padStart(16,'0')
fun p(){(0..3).map{print("+---")}
println("+")}
(0..3).map{p()
v.subSequence(it*4,(it+1)*4).map{print("| ${if(it>'0')'#' else ' '} ")} println("|")} p()}  ## Beautified { val v = it.toString(2).padStart(16, '0') fun p() { (0..3).map { print("+---") } println("+") } (0..3).map { p() v.subSequence(it *4, (it +1) *4).map {print("|${if (it > '0') '#' else ' '} ")}
println("|")
}
p()
}


## Test

var b:(Int) -> Unit =