# Matrix Meets ASCII Art

A binary matrix represents a shape in the plane. 1 means a unit square at that position. 0 means nothing. The background is 0.

For example, the array [[0,1,0],[0,0,1],[1,1,1]] represents the following shape:

     o----o
|////|
|////|
o----o----o
|////|
|////|
o----o----o----o
|////|////|////|
|////|////|////|
o----o----o----o


# Challenge

You take input as the array and output the matching ASCII art.

# Examples

[[1,1,1],[0,0,0]]

o----o----o----o
|////|////|////|
|////|////|////|
o----o----o----o


(You may or may not trim)

[[0,1,0],[1,0,1]]

     o----o
|////|
|////|
o----o----o----o
|////|    |////|
|////|    |////|
o----o    o----o


[[1,0,1,0],[0,0,0,0],[1,1,1,0]

o----o    o----o
|////|    |////|
|////|    |////|
o----o    o----o

o----o----o----o
|////|////|////|
|////|////|////|
o----o----o----o


[[1]]

o----o
|////|
|////|
o----o


You can choose whether or not to trim surrounding whitespace, from either rows, columns, both or neither

• May we take the input as something like 0 1 0\n0 0 1\n1 1 1 if our language does not support arrays?
– Dion
10 hours ago
• @Dion Yes...... 9 hours ago

# Python, 232223 209 bytes

-9 bytes thanks to @Kevin Cruijssen

-11 bytes thanks to @a stone arachnid

-3 bytes thanks to @Steffan

def f(a):R=range;E=enumerate;s=[[*" "*6*len(_)]for _ in 4*a];[s[I+3*i].__setitem__(J+j*5,"/|-o"[2*(I%3<1)+(J%5<1)])for i,r in E(a)for j,x in E(r)if x for I in R(4)for J in R(6)];print(*map("".join,s),sep="\n")

Attempt This Online!

• Both ==0 can be <1 and [" "for _ in R(6*len(a[0]))] can be list(" "*6*len(a[0])) May 10 at 10:01
• Works!!!!!!!!!! May 10 at 10:15
• and list(" "*6*len(_)) can be [*" "*6*len(_)] May 11 at 3:50

# Charcoal, 33 bytes

ＦＡ«Ｆι«ＦκＰ”{⊟∨¹↖﹪Ｈ✂sρSjυ%‖”Ｍ⁵→»⸿⸿⸿


Try it online! Link is to verbose version of code. Explanation:

ＦＡ«


Loop through the rows.

Ｆι«


Loop through the cells of this row.

ＦκＰ”{⊟∨¹↖﹪Ｈ✂sρSjυ%‖”


If this cell is 1 then output a compressed representation of the shape without moving the cursor.

Ｍ⁵→


In any case move the cursor five characters to the right. This causes adjacent shapes to overlap by one character.

»⸿⸿⸿


After each row move the cursor to the start of the bottom row of the current line, so that the next row will overlap by one character.

Drawing the shape using Charcoal commands turns out to also take 33 bytes:

ＦＡ«Ｆι«Ｆκ«Ｆ²Ｆ²«o⁻⁴⊗ν↷»↘¤/↖»Ｍ⁵→»⸿⸿⸿


Try it online! Link is to verbose version of code. Explanation: As above, except instead of Ｐ”{⊟∨¹↖﹪Ｈ✂sρSjυ%‖”:

Ｆ²Ｆ²«o⁻⁴⊗ν↷»


Draw a rectangle with os at the corners.

↘¤/↖


Fill the rectangle with /s.

If +s had been acceptable for corners then Ｆ²Ｆ²«o⁻⁴⊗ν↷» could have been replaced with Ｂ⁶¦⁴ saving eight bytes.

ＦＡ«Ｆι«Ｆκ«Ｂ⁶¦⁴↘¤/↖»Ｍ⁵→»⸿⸿⸿


Try it online! Link is to verbose version of code.

• Works!!!!!!!!!! May 10 at 10:14

# Perl 5 + -pl, 77 bytes

$"="..[6D";s!.!@{[$&?qw(o----o |////|)[0,1,1,0]:(".[6C")x4]}.[3A.!g;$\=".[3E" Try it online! Contains unprintable characters and uses ANSI escape codes to reposition the cursor and output the required ASCII art. Long arrays may not display correctly in the browser (as the terminal is a fixed height and the cursor cannot move out of bounds). Happy to delete if this is not to spec! ## Explanation First, we set the list separator variable ($" - this is automatically added to string when a list is interpolated into it) to a string that will move the cursor down 1 line (form feed - \x0c) and back 6 characters (\x1b[6D). Then s///ubstitute each char (.) in (the implicit, stored in $_, via -p) input with an inline interpolated array (@{[...]}) that contains either the four parts of the box (qw(o----o |////|)[0,1,1,0]) or four repetitions of moving the cursor forward six characters (("\x1b[6C")x4), depending on whether or not the currently matched character ($&) is truthy. At the end of the string the cursor is moved back up three lines (\x1b[3A) and a literal backspace moves the cursor back one character (\x08). Finally, the output record separator ($\) is set to a string that moves the cursor to the beginning of the line three lines down (\x1b[3E), which is automatically printed (along with the modified input). • Works!!!!!!!!!! May 11 at 0:28 # JavaScript, 182 bytes m=>m.map(g=r=>((p=(L=( |[r[0]]+r.map((d,x)=>d?////|: + |[r[x+1]|0]).join+ ))[R='replace'](/\//g,'-')[R](/\|/g,'o'))[R](/ /g,(c,i)=>P[i]||' '))+(P=p,L)+L,P='').join+P  Can probably be golfed a lot more. f= m=>m.map(g=r=>((p=(L=( |[r[0]]+r.map((d,x)=>d?////|: + |[r[x+1]|0]).join+ ))[R='replace'](/\//g,'-')[R](/\|/g,'o'))[R](/ /g,(c,i)=>P[i]||' '))+(P=p,L)+L,P='').join+P ; console.log(f([ [1,1,1], [0,0,0] ])); console.log(f([ [0,1,0], [1,0,1] ])); console.log(f([ [1,0,1,0], [0,0,0,0], [1,1,1,0] ])); console.log(f([ [1] ])); console.log(f([ [1,0,1,0], [1,0,0,0], [0,0,0,1], [1,1,1,0] ])); # J, 58 bytes ' -o/|'{~(1 3 3 1+/#:33)>./@((]$_3 _5&*@#:I.@,)|.*&$~{.[)]  Try it online! Consider input:  0 1 0 0 0 1 1 1 1  • (1 3 3 1+/#:33) Create a numeric matrix representing the ascii "cell": 2 1 1 1 1 2 4 3 3 3 3 4 4 3 3 3 3 4 2 1 1 1 1 2  • *&$~{.[ Multiply dimensions of that times dimensions of input, ie, 4 6 * 3 3, giving 12 18, and extend our cell to those dimensions, which will always be slightly bigger than we need:

2 1 1 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0
4 3 3 3 3 4 0 0 0 0 0 0 0 0 0 0 0 0
4 3 3 3 3 4 0 0 0 0 0 0 0 0 0 0 0 0
2 1 1 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

• Our strategy will be to rotate the above matrix in 2 dimensions, one time for each 1, moving the cell into each require position.

• \$...#:I.@, Convert the positions of the ones into 2d coordinates:

 0 1
1 2
2 0
2 1
2 2

• _3 _5&*@ Multiply row-wise by "dimensions of cell, minus 1, negated". The negation is needed because we want to rotate right rather than left.

 0  _5
_3 _10
_6   0
_6  _5
_6 _10

• |. Create multiple copies of our "extended" cell, rotating by those amounts:

0 0 0 0 0 2 1 1 1 1 2 0 0 0 0 0 0 0
0 0 0 0 0 4 3 3 3 3 4 0 0 0 0 0 0 0
0 0 0 0 0 4 3 3 3 3 4 0 0 0 0 0 0 0
0 0 0 0 0 2 1 1 1 1 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 2 1 1 1 1 2 0 0
0 0 0 0 0 0 0 0 0 0 4 3 3 3 3 4 0 0
0 0 0 0 0 0 0 0 0 0 4 3 3 3 3 4 0 0
0 0 0 0 0 0 0 0 0 0 2 1 1 1 1 2 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2 1 1 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0
4 3 3 3 3 4 0 0 0 0 0 0 0 0 0 0 0 0
4 3 3 3 3 4 0 0 0 0 0 0 0 0 0 0 0 0
2 1 1 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 2 1 1 1 1 2 0 0 0 0 0 0 0
0 0 0 0 0 4 3 3 3 3 4 0 0 0 0 0 0 0
0 0 0 0 0 4 3 3 3 3 4 0 0 0 0 0 0 0
0 0 0 0 0 2 1 1 1 1 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 2 1 1 1 1 2 0 0
0 0 0 0 0 0 0 0 0 0 4 3 3 3 3 4 0 0
0 0 0 0 0 0 0 0 0 0 4 3 3 3 3 4 0 0
0 0 0 0 0 0 0 0 0 0 2 1 1 1 1 2 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

• >./@ Max reduce these "planes" to create a single matrix, which handles the overlapping corners:

0 0 0 0 0 2 1 1 1 1 2 0 0 0 0 0 0 0
0 0 0 0 0 4 3 3 3 3 4 0 0 0 0 0 0 0
0 0 0 0 0 4 3 3 3 3 4 0 0 0 0 0 0 0
0 0 0 0 0 2 1 1 1 1 2 1 1 1 1 2 0 0
0 0 0 0 0 0 0 0 0 0 4 3 3 3 3 4 0 0
0 0 0 0 0 0 0 0 0 0 4 3 3 3 3 4 0 0
2 1 1 1 1 2 1 1 1 1 2 1 1 1 1 2 0 0
4 3 3 3 3 4 3 3 3 3 4 3 3 3 3 4 0 0
4 3 3 3 3 4 3 3 3 3 4 3 3 3 3 4 0 0
2 1 1 1 1 2 1 1 1 1 2 1 1 1 1 2 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

• ' -o/|'{~ Convert to ascii:

o----o
|////|
|////|
o----o----o
|////|
|////|
o----o----o----o
|////|////|////|
|////|////|////|
o----o----o----o


# C (clang), 198 197 bytes

-1 byte thanks to @ceilingcat.

Based on @Matteo C.'s Python answer.

#define F(_,t)for(_=t;_--;)
i;j;I;J;f(*a,X,Y){char*s[3*X+1];F(i,4*X)asprintf(s+i,"%*c",Y*5,0);F(i,X)F(j,Y)if(a[i*Y+j])F(I,4)F(J,6)s[I+3*i][J+j*5]="/|-o"[2*!(I%3)+!(J%5)];F(i,j=3*X+1)puts(s[j+~i]);}


Try it online! Takes input as the matrix as a flattened array, the number of rows in the matrix, and the number of elements in each row.

• Suggest j+~i instead of j-1-i 2 days ago