36
\$\begingroup\$

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! :-)

\$\endgroup\$
10
  • 1
    \$\begingroup\$ Related \$\endgroup\$
    – Sp3000
    Sep 18, 2015 at 16:38
  • 2
    \$\begingroup\$ 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. \$\endgroup\$ Sep 18, 2015 at 16:44
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ Sep 18, 2015 at 17:53
  • \$\begingroup\$ Does writing a function with the base-10 number as the function argument count as user input? \$\endgroup\$
    – Alex A.
    Sep 18, 2015 at 18:12
  • 2
    \$\begingroup\$ 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. \$\endgroup\$ Sep 18, 2015 at 18:20

38 Answers 38

24
\$\begingroup\$

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.)

\$\endgroup\$
3
  • \$\begingroup\$ 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. \$\endgroup\$ Sep 18, 2015 at 20:30
  • 5
    \$\begingroup\$ @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. \$\endgroup\$
    – Dennis
    Sep 18, 2015 at 20:45
  • \$\begingroup\$ Thanks for the response @Dennis. I'm happy my presumption was incorrect, then, because I (still) really like Mauris' solution! :-) \$\endgroup\$ Sep 18, 2015 at 20:57
14
\$\begingroup\$

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>

\$\endgroup\$
4
  • 6
    \$\begingroup\$ Is "JavaScripy" some strange javascript/python mashup? ;-) \$\endgroup\$ Sep 18, 2015 at 20:52
  • 6
    \$\begingroup\$ @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 \$\endgroup\$
    – edc65
    Sep 18, 2015 at 21:07
  • \$\begingroup\$ Cool, this works on Edge! \$\endgroup\$ Sep 20, 2015 at 5:36
  • 1
    \$\begingroup\$ Must... not... click... tvtropes... \$\endgroup\$
    – RK.
    Sep 21, 2015 at 18:22
14
\$\begingroup\$

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!

\$\endgroup\$
11
\$\begingroup\$

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

\$\endgroup\$
11
\$\begingroup\$

Python 2, 157 153 151 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
+---+---+---+---+
| # |   |   |   |
+---+---+---+---+
|   | # |   |   |
+---+---+---+---+
|   |   | # |   |
+---+---+---+---+
|   |   |   | # |
+---+---+---+---+
\$\endgroup\$
4
  • \$\begingroup\$ You can save two bytes if you pull '+---'*4 into a variable and two more if you do j=''.join \$\endgroup\$ Sep 18, 2015 at 19:50
  • \$\begingroup\$ No problem! I was actually working on a very similar solution. \$\endgroup\$ Sep 18, 2015 at 19:57
  • \$\begingroup\$ @downvoter Care to explain? \$\endgroup\$
    – Zach Gates
    Sep 10, 2017 at 21:26
  • \$\begingroup\$ Since you do not use Python 3, you can replace int(input()) with input() and save five bytes. \$\endgroup\$ Sep 10, 2017 at 23:53
9
\$\begingroup\$

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 
+---+---+---+---+
| # |   |   |   |
+---+---+---+---+
|   | # |   |   |
+---+---+---+---+
|   |   | # |   |
+---+---+---+---+
|   |   |   | # |
+---+---+---+---+
$ 
\$\endgroup\$
3
  • \$\begingroup\$ 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. \$\endgroup\$ Sep 18, 2015 at 20:59
  • \$\begingroup\$ @type_outcast BTW its perfectly OK to post your own solution as an answer :) \$\endgroup\$ Sep 18, 2015 at 21:04
  • \$\begingroup\$ 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. \$\endgroup\$ Sep 18, 2015 at 21:07
9
\$\begingroup\$

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.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can save some bytes if you write literal characters using the ? notation (ex: ?| instead of '|'). This works for everything except space. \$\endgroup\$ Sep 19, 2015 at 12:03
  • \$\begingroup\$ @w0lf I have found that ?\s works for space, however it is not actualy helpful here. \$\endgroup\$
    – Mohammad
    Sep 20, 2015 at 17:41
6
\$\begingroup\$

C++11, 193 191 190 176 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");
    }
}
\$\endgroup\$
7
  • \$\begingroup\$ Hint: 0x10000 is 65536, having '0x' prefix, hex is always longer than decimal \$\endgroup\$
    – edc65
    Sep 18, 2015 at 20:27
  • \$\begingroup\$ Hint 2: youd should avoid using namespace std in production code. And it's not useful here too. \$\endgroup\$
    – edc65
    Sep 18, 2015 at 20:29
  • \$\begingroup\$ @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. \$\endgroup\$
    – Zereges
    Sep 18, 2015 at 20:31
  • \$\begingroup\$ Hey Zereges. You can remove the space between the include and the library.. and remove the return type for the main function. \$\endgroup\$ Sep 18, 2015 at 20:39
  • \$\begingroup\$ C++ does not support auto int. \$\endgroup\$
    – Zereges
    Sep 18, 2015 at 20:40
6
\$\begingroup\$

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
\$\endgroup\$
5
\$\begingroup\$

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.

Try it online.

\$\endgroup\$
4
\$\begingroup\$

Python 2, 122 121 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.

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

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.

\$\endgroup\$
4
\$\begingroup\$

PowerShell, 203 188 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$l`n"}})-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.


Previous, 188

param($a)$l="+---+---+---+---+";$l;$b=([int64][convert]::ToString($a,2)).ToString(@(,"0"*16)-join'');$o=@(1..16|%{if($b[$_-1]-eq'1'){"| # "}else{"|   "};if($_%4-eq0){"|`n$l`n"}});$o-join''

Previous-er, 203

param($a)$l="+---+---+---+---+`n|";$o=$l;$b=([int64][convert]::ToString($a,2)).ToString(@(,"0"*16)-join'');1..16|%{if($b[$_-1]-eq'1'){$o+=" # |"}else{$o+="   |"};if($_%4-eq0){$o+="`n$l"}};$o.TrimEnd('|')
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I hope it was a "fun hard". :-) +1 for your explanation; it helped my limited understanding of PowerShell. \$\endgroup\$ Sep 18, 2015 at 21:04
3
\$\begingroup\$

Javascript (ES6), 216 207 bytes

Defines an anonymous function.

i=>(","+("0".repeat(16)+i.toString(2)).slice(-16).split``.map((v,l,a)=>l%4<1?"| "+a.slice(l,l+4).map(v=>v?"#":" ").join` | `+" |":"").filter(v=>!!v).join`,`+",").replace(/,/g, `
+---+---+---+---+
`).slice(1)

Thanks to ETHproductions for tips!

\$\endgroup\$
4
  • \$\begingroup\$ Nice work! Since you're using ES6, here's a few tips: 1. Anytime you need to use a string as a function's only parameter, you can use a template string, like so: .join` | `​ 2. You can also use template strings for interpolating values: i=>`,${"0".repeat....join`,`},`.replace... 3. You can find more ES6 tips on this thread. \$\endgroup\$ Sep 18, 2015 at 20:25
  • \$\begingroup\$ 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) \$\endgroup\$ Sep 18, 2015 at 22:34
  • 2
    \$\begingroup\$ ("0".repeat(16)+i.toString(2)).slice(-16) --> (65536|i).toString(2).slice(1) \$\endgroup\$
    – edc65
    Sep 19, 2015 at 0:36
  • \$\begingroup\$ Keeping your exact logic, this can be golfed to 169, see jsfiddle.net/76fp7aw6 \$\endgroup\$
    – edc65
    Sep 19, 2015 at 13:40
3
\$\begingroup\$

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: 
C3              RET                         ; return to caller
            SEP DB  '+---+---+---+---+',0DH,0AH,'$'
            ROW DB  '|   |   |   |   |',0DH,0AH,'$'

Callable function, input in BX output to STDOUT.

Example test program:

enter image description here

\$\endgroup\$
2
\$\begingroup\$

CJam, 62 bytes

"+---|   "4/{4*_c+N+}%4*_0=]sqi2bG0e[ee{~{_9*\4%5*-K+'#t0}&;}/

Try it online.

\$\endgroup\$
2
\$\begingroup\$

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!

\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

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).

\$\endgroup\$
2
\$\begingroup\$

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)));
\$\endgroup\$
0
2
\$\begingroup\$

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!

\$\endgroup\$
1
  • \$\begingroup\$ Nice, much better approach than mine! A literal newline will save you an extra byte over $/ too! \$\endgroup\$ Sep 11, 2017 at 12:16
2
\$\begingroup\$

Vyxal j, 47 bytes

b:L16-(0p)4ẇƛƛ‛ #$i`| % `$%;ṅ\|+;\+:3-4*pw5ẋf$Y

Try it Online! A big mess

\$\endgroup\$
2
  • \$\begingroup\$ You sure there isn't a flag that can be used here? \$\endgroup\$
    – lyxal
    Jun 14, 2021 at 6:24
  • \$\begingroup\$ @lyxal True, forgot \$\endgroup\$
    – emanresu A
    Jun 14, 2021 at 6:25
2
\$\begingroup\$

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
\$\endgroup\$
2
\$\begingroup\$

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
\$\endgroup\$
1
  • \$\begingroup\$ Nice! Appreciate you de-golfing it for us mere mortals, not to mention coming back with another solution after so long. \$\endgroup\$ Nov 25, 2022 at 1:47
2
\$\begingroup\$

Uiua, 48 46 45 bytes

⊏:"+-| #"⍜♭(⇌⍜▽◌=4.)↘1▽5⊟+2↧⇌.⟜±◿4⇡17+3⋯+ⁿ8 4

Try it!

My thought was to do a direct construction approach, as opposed to what other solutions are mostly doing which is building the output in a loop.

The bulk of the work is building the following matrix:

[[0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0]
 [2 3 4 3 2 3 4 3 2 3 4 3 2 3 4 3 2]
 [0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0]
 [2 3 4 3 2 3 4 3 2 3 4 3 2 3 4 3 2]
 [0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0]
 [2 3 4 3 2 3 4 3 2 3 4 3 2 3 4 3 2]
 [0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0]
 [2 3 4 3 2 3 4 3 2 3 4 3 2 3 4 3 2]
 [0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0]]

Both rows are built by starting with the range [0, 17) modulo 4:

⇡17  [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
◿4   [0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0]

     first row:
     [0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0]
±    [0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0]

     second row:
     [0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0]
⇌    [0 3 2 1 0 3 2 1 0 3 2 1 0 3 2 1 0]
↧    [0 1 2 1 0 1 2 1 0 1 2 1 0 1 2 1 0]
+2   [2 3 4 3 2 3 4 3 2 3 4 3 2 3 4 3 2]

The two rows are paired together and repeated 5 times, with the extra row removed.

Take the binary representation of the input, padded to 16 bits by adding ⁿ8 4 (4^8 is a byte shorter than 2^16). Add three to each digit, leaving 3 where there'd been zeros and 4 where there'd been ones. Then replace each four in the above matrix with a number from this list.

Finally, index each item into a string so that 0 becomes +, 1 becomes -, 2 becomes |, 3 becomes space, and 4 becomes #.

\$\endgroup\$
2
\$\begingroup\$

05AB1E, 31 bytes

b16jT„# ‡4äε€'|Ć"+---"17∍‚}€`Ć»

Try it online or verify both test cases.

Building the box first with placeholder-character and then replacing that placeholder with the #/ seems to be the exact same byte-count:

"+---"17∍'|X2F‚9∍}»$žH+„ #Åв¦.;

Try it online or verify both test cases.

Explanation:

b               # Convert the (implicit) input-integer to a binary-string
 16j            # Pad leading spaces to make the length 16
    T           # Push 10
     „#         # Push "# "
        ‡       # Transliterate all "1"s to "#"s and "0"s to " "s
         4ä     # Split it into 4 equal-sized strings
ε               # Map over each string of "#"s and spaces:
 €'|           '#  Convert it to a list of characters, and place a "|" before each
    Ć           #  Enclose; append its own head (append "|")
     "+---"     #  Push string "+---"
           17∍  #  Extend it to size 17: "+---+---+---+"
              ‚ #  Pair the list and this string together
}€`             # After the map: revert each inner pair, and then flatten one level down
   Ć            # Enclose; append its own head (append "+---+---+---+")
    »           # Join each inner list of characters by spaces,
                # and then all strings by newlines
                # (after which the result is output implicitly, with trailing newline)
"+---"17∍       # Same as above: push "+---+---+---+"
'|             '# Push "|"
  X             # Push 1
   2F           # Loop 2 times:
     ‚          #  Pair the top two values on the stack together
      9∍        #  Extend this pair to size 9
    }»          # After the loop: join each inner list by spaces,
                # and then all strings by newlines
$               # Push 1 and the input
 žH+            # Add constant 65536 to the input
    „ #Åв       # Convert it to custom base-" #",
                # basically convert it to base 2, and 0-based index into " #"
         ¦      # Remove the leading "#"
          .;    # Replace all 1s in the box one-by-one with these characters
                # (after which the result is output implicitly, with trailing newline)
\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

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}}
\$\endgroup\$
1
\$\begingroup\$

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}
\$\endgroup\$
1
\$\begingroup\$

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)
    {
        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;
    }
}

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

\$\endgroup\$
3
  • \$\begingroup\$ Firstly, I count 286 bytes and you can remove the indentation spaces. \$\endgroup\$
    – Blue
    Sep 21, 2015 at 17:57
  • \$\begingroup\$ 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! \$\endgroup\$ Sep 21, 2015 at 18:03
  • \$\begingroup\$ Use something like mothereff.in/byte-counter, or if you're on linux, use the wc command \$\endgroup\$
    – Blue
    Sep 21, 2015 at 18:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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