38
\$\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
    Commented 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\$ Commented 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\$ Commented 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.
    Commented 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\$ Commented Sep 18, 2015 at 18:20

39 Answers 39

1
2
1
\$\begingroup\$

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

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

05AB1E, 45 bytes

bDg16αúS4ôεεð.ø}õ.ø'|ý}õ.ø…+--3F.∞}¶.øý10„# ‡

Try it online!

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

JavaScript (Node.js), 82 bytes

f=(x,i=16,h=`+---+---+---+---+
`)=>i?f(x/2,i-1)+"| "+" #"[x&1]+(i%4?" ":` |
`+h):h

Try it online!

Or try it with the interactive snippet below.

f=(x,i=16,h=`+---+---+---+---+
`)=>i?f(x/2,i-1)+"| "+" #"[x&1]+(i%4?" ":` |
`+h):h

I.oninput=()=>O.innerHTML=f(+I.value);
I.oninput();
<input id=I type=number min=0 max=65535 value=4242><br/>
<pre id=O>

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

sed 4.2.2 -rn, 109 108 107 105 104 bytes

-1 byte thanks to noodle man

s/.*/dc<<<4dvo8^&+p/e   #convert N#10 to N+4^(8)#sqrt(4)
s/.//                   #subtract 2^16
y/01/ #/                #convert 0 to &nbsp; and 1 to #
s//| & /g               #put each one in a box
x                       #swaps PATTERN and HOLD spaces
s/.*/+---/              #replace ALL with +---
s//&&&&+/p              #replace PREV EXPR with MATCH 4 times and +, and print
:                       #define label ''                           (begin loop)
x                       #swaps PATTERN and HOLD spaces                        |
s/ / |\n/8              #add |\n after the 8th space, if it exists            |
P                       #print the first line of the PATTERN space            |
s/.*\n//                #delete everything up to and including a \n           |
/-/b                    #if there's a -, branch to ''                         |
t                       #if successful swap statement, jump to ''    (end loop)

Try it online!

heh, apperently I took just about the oppsite approach as the other sed answer, building and printing it out one line at a time instead of building it inside of the PATTERN space and printing at the end.

it seems like there were so many optimizations that only gave me one byte back with this one, apperently you made a challenge that's just barely past the point that makes lots of optimizations worth it in sed. like 2^16 instead of 65536 only saves one byte, and +--- x4 is only one byte better than printing it all out, and combining the last two ss only saved one byte, and lots of other things like that...

I feel like this could almost certainly be done in under 100 bytes, I'll come back to this later to see if I can get anything else off of it.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can probably save another byte with 4^8 instead of 2^16 \$\endgroup\$ Commented Apr 16 at 11:07
  • \$\begingroup\$ @noodleman apperently 4^8 in base sqrt(4), 4^8 in base 2, and 2^16 in base 2 are all the same number of bytes \$\endgroup\$
    – guest4308
    Commented Apr 16 at 13:54
1
\$\begingroup\$

Go, 187 bytes

func(n uint16)(s string){H,N:="+---+---+---+---+",`
`
s+=H
for i:=0;i<4;i++{for j:=0;j<4;j++{if j<1{s+=N+"|"}
c:=" "
if n>>(16-(4*i+j+1))&1>0{c="#"}
s+=" "+c+" |"
if j>2{s+=N+H}}}
return}

Attempt This Online!

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

Python 3, 110 121 119 115 bytes

(+11 bytes to handle user input, -6 bytes thanks to @noodle man!)

Had a lot of fun with this one. I think there are probably some bytes that can be knocked off, but I am happy with it for now!

def f(n):
 i=1;e=a='+---'*4+'+\n'
 for x in f'{n:016b}':e+=['|   ','| # '][int(x)]+('|\n'+a)*(i%4<1);i+=1
 print(e)

Try it online!

Explanation

                              ## Initialise variables
j=['|   ','| # ']             #  0->' ' and 1->'#' 
m=f'{int(input()):016b}'      #  Input to 16 digit binary
i=1                           #  i=1
a='+---'*4+'+\r\n'            #  a = +---+---+---+---+
e=a                           #  Initialise output to above
for x in m:                   ## Loop through binary digits
    e+=j[int(x)]              #  Convert to ' ' or '#'
    e+=('|\r\n'+a)*(i%4<1)    #  Every 4th loop, newline and a
    i+=1                      #  Increment i

As an aside, I had some fun figuring out some 16-bit graphics without converting to binary:

30855             44441             34966             44441
+---+---+---+---+ +---+---+---+---+ +---+---+---+---+ +---+---+---+---+
|   | # | # | # | | # |   | # |   | | # |   |   |   | | # |   | # |   |
+---+---+---+---+ +---+---+---+---+ +---+---+---+---+ +---+---+---+---+
| # |   |   |   | | # | # |   | # | | # |   |   |   | | # | # |   | # |
+---+---+---+---+ +---+---+---+---+ +---+---+---+---+ +---+---+---+---+
| # |   |   |   | | # |   |   | # | | # |   |   | # | | # |   |   | # |
+---+---+---+---+ +---+---+---+---+ +---+---+---+---+ +---+---+---+---+
|   | # | # | # | | # |   |   | # | |   | # | # |   | | # |   |   | # |
+---+---+---+---+ +---+---+---+---+ +---+---+---+---+ +---+---+---+---+
\$\endgroup\$
6
  • 1
    \$\begingroup\$ Note that the question explicitly disallows hard coded input. You can replace n with int(input()) to fix it, but this increases the byte count to 121. \$\endgroup\$ Commented Apr 17 at 11:45
  • 1
    \$\begingroup\$ Nice solution, as The Empty String Photographer pointed out you may not hard-code the input. You could instead take the input from function arguments, which would be a bit shorter \$\endgroup\$ Commented Apr 17 at 12:43
  • \$\begingroup\$ Ahh, I missed that when parsing the question. I've added int(input()) as @The Empty String Photographer suggested, taking me to 121 bytes \$\endgroup\$
    – cnln
    Commented Apr 17 at 13:27
  • 1
    \$\begingroup\$ this is still not valid yet, since you need to count the print(e). here’s 119 bytes, as a function, with some golfs \$\endgroup\$ Commented Apr 17 at 13:43
  • 1
    \$\begingroup\$ You can save another 4 bytes by inlining j since it’s only used in one place \$\endgroup\$ Commented Apr 17 at 14:53
1
\$\begingroup\$

Scala 3, 220 bytes

220 bytes, it can be golfed more.


Ungolfed version. Attempt This Online!

n=>{val b=n.toBinaryString.reverse.padTo(16,'0').reverse;val m=b.grouped(4).toArray;val l="+"+("---+"*4);for(i<-0 to 3){println(l);val r=m.map(c=>if(c(i)>'0')"#"else" ").mkString("| "," | "," |");println(r)};println(l);}

Golfed version. Attempt This Online!

object Main {
  def main(args: Array[String]): Unit = {
    f(33825)
  }

  def f(n: Int): Unit = {
    val b = n.toBinaryString.reverse.padTo(16, '0').reverse
    val m = b.grouped(4).toArray
    val l = "+" + ("---+" * 4)

    for (i <- 0 until 4) {
      println(l)
      val row = m.map(col => if (col(i) > '0') "#" else " ").mkString("| ", " | ", " |")
      println(row)
    }
    println(l)
  }
}
\$\endgroup\$
0
\$\begingroup\$

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 =
{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()}

fun main(args: Array<String>) {
    b(255)
}
\$\endgroup\$
0
\$\begingroup\$

Pip, 85 bytes

a:TBa
(("   "X16-#a).aR0"   "R1" # "<>3JW'|<>16J'|<>17JWn."+---+---+---+---+".n)@<-20

Does a straightforward bunch of splits and replacement to get the final grid.

Try it online!

\$\endgroup\$
1
2

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.