Given an ASCII operator from the list below and a number n, draw an ASCII representation of the operator using that operator as the character with the line segments of the operator having length n.


An ASCII character from the list = + - x / and an integer n where n >= 1. (I'm using x instead of * and / instead of ÷, but you could use either one, whichever is easier). For + and x, you only have to handle odd numbers to avoid issues with alignment.


An ASCII drawing of the operator composed of the character with segments of length n. Horizontal portions should have spaces between the characters to offset vertical/horizontal distance differences.


This is , so shortest code in bytes wins. Standard loopholes are forbidden.


Input: + 3

+ + +

Input: = 4

= = = =
= = = =

Input: = 10

= = = = = = = = = =
= = = = = = = = = =

Input: - 2

- -

Input: / 10


Input: x 7

x     x
 x   x
  x x
  x x
 x   x
x     x
  • \$\begingroup\$ can you add the test case for = 10? \$\endgroup\$
    – Rod
    Nov 7, 2016 at 16:40
  • 1
    \$\begingroup\$ I assume "x" and "+" imply odd numbers? (I just saw DrMcMoylex asked nearly the same question.) \$\endgroup\$ Nov 7, 2016 at 16:48
  • 1
    \$\begingroup\$ @MartinRosenau Yes, from the Input section: "For + and x, you only have to handle odd numbers to avoid issues with alignment." \$\endgroup\$
    – corvus_192
    Nov 7, 2016 at 17:01
  • \$\begingroup\$ Why are X and / not spaced out? \$\endgroup\$
    – Adám
    Nov 8, 2016 at 11:37
  • 1
    \$\begingroup\$ is leading whitespace allowed? \$\endgroup\$
    – Adám
    Nov 8, 2016 at 12:15

15 Answers 15


V, 78, 72, 71, 68, 65, 63, 62, 61 bytes

Ç=ü-/Àé X
ç^Ó/é Àä$

Try it online!

As always, the neck-and-neck battle with 05AB1E is really fun!

Since this contains non-ASCII characters, here is a hexdump:

0000000: c73d fc2d 2fc0 e920 580a e75e d32f e920  .=.-/.. X..^./. 
0000010: c0e4 240a e72b 2fc0 c44d 7cc0 522b 200a  ..$..+/..M|.R+ .
0000020: e73d 2fc4 0ae7 af2f 6cf2 6859 7058 0ae7  .=/..../l.hYpX..
0000030: 782f 7278 f26c 33c4 6a78 6c72 78         x/rx.l3.jxlrx

This does create leading spaces in the output for = and -, but this seems to be allowed. If this is not allowed, feel free to comment and I'll roll it back.


The "global command" (e.g. ç) applies a certain set of commands to every line that matches a certain regex. The syntax is

ç<compressed regex>/<commands>

This is the easiest way of simulating a conditional/switch statement. In my original answer, I simply created the entire ASCII-art on the right-hand side for each different character we need to search for. However, a lot of these outputs require similar commands. So I combined them. The first command ('Ç') is actually the inverse of the global command, it applies the command to every line not matching the regex. So the first command is:

Ç=ü-        " On every line not containing an '=' or an '-' (e.g. inputs '/', '+', and 'x'):
    /Àé     "   Insert *n* spaces
        X   "   Delete one of them

The following command is for inputs '=' and '-'. These two are conveniently easy and similar. After this command, we need no more processing for -.

ç^Ó         " On every line that starts with non-whitespace (e.g. every line not affected by our previous command):
   /é       "   Insert one space
            "   Move back a character
      À     "   Make *n* copies
       ä$   "   Of every character on this line

From here we just do some extra commands for each individual possible input. For +:

ç+/         " On every line containing a '+':
   ÀÄ       "   Make *n* copies of this line
     M|     "   Move to the first character of the middle line
       À    "   *n* times:
        R+  "   Replace the next two characters with '+ '

The command for equals is very straightforward. We just duplicate it with Ä. For /:

ç¯          " On every line containing a '/':
  /l        "   Move one character to the right
    ò       "   Recursively:
     h      "     Move one character to the left
      Yp    "     Make a copy of this line
        X   "     Delete one character
         ò  "   End loop (implicit)

The last one is the most complicated. It is basically a port of this answer.

çx              " On every line containing a 'x':
  /rx           "   Replace the first character with an 'x'
     ò          "   Recursively:
      l         "     Move one char to the right
       3Ä       "     Make 3 copies of this line
         j      "     Move down one line
          x     "     Delete one char
           l    "     Move one char to the right
            rx  "     Replace this char with an 'x'
  • \$\begingroup\$ so is that what multiple lines are used for? \$\endgroup\$ Nov 8, 2016 at 12:48
  • \$\begingroup\$ @Conorobrien Yes. The ç command (as well as search and replace, / and ?) all simulate part of vim's command line, where you have to hit enter to actually run the command \$\endgroup\$
    – DJMcMayhem
    Nov 8, 2016 at 14:09

05AB1E, 81 76 74 73 70 69 68 65 64 62 60 59 57 56 bytes

Currently in war with the V answer. I'm coming for you Dr. McMoylex :p.

Also in war with the Pip answer. I'll be watching you Mr. DLosc.


Ç6&"¹s<ú.s.Bívy¹'xQiÂðñ}, ¹×S)»¹'=Qƒ= ;ƒ¹})D¦»»Rû.c"#è.V

Or in a more readable form:


Uses the CP-1252 encoding. Try it online!

  • 1
    \$\begingroup\$ Here we go again... :P \$\endgroup\$
    – DJMcMayhem
    Nov 7, 2016 at 17:53
  • 1
    \$\begingroup\$ @DrMcMoylex Hahaha, good old times :). \$\endgroup\$
    – Adnan
    Nov 7, 2016 at 17:53
  • 30
    \$\begingroup\$ More readable... totally... \$\endgroup\$
    – Oliver Ni
    Nov 7, 2016 at 17:56
  • 1
    \$\begingroup\$ For a given definition of "readable". \$\endgroup\$
    – Matt Lacey
    Nov 8, 2016 at 22:23
  • 1
    \$\begingroup\$ I'm coming for you, Adnan :P \$\endgroup\$
    – DLosc
    Nov 10, 2016 at 16:01

Python 3, 304 283 278 bytes

Simple enough, just makes a matrix of chars and applies the different operations based on which one it is. The = and - have trailing spaces if that's not too bad.

EDIT: Thanks to @Shebang and @Rod for their suggestions which ended up saving 21 bytes!

EDIT2: Thanks to @Artyer for saving 5 bytes!

b=[[' ']*s for x in r]
exec(['for x in r:b[s//2][x]=b[x][s//2]=t','b=[t*s]'+'*2'*(t=='='),'for x in r:b[x][s-x-1]='+'b[x][x]='*(t=='x')+'t'][(t>'+')+(t in'x/')])
if t in'-=+':b=[[x+' 'for x in l]for l in b]
  • \$\begingroup\$ You can save 8 bytes by removing the if'-'==t condition line and replacing the one above it with if t in'=-':b=[[t+' ']*s]*(2*(t>'-')) (I think). \$\endgroup\$
    – Kade
    Nov 7, 2016 at 17:25
  • \$\begingroup\$ you can wrap the functions inside a list and run using exec: exec(['+ block','/ block','x block','= block','- block']['+/x=-'.find(t)]) to save ~18 bytes \$\endgroup\$
    – Rod
    Nov 7, 2016 at 17:31
  • \$\begingroup\$ Yes, trailing spaces/newlines are acceptable. \$\endgroup\$
    – Yodle
    Nov 7, 2016 at 17:41
  • \$\begingroup\$ For the first line, do .split() (No args splits on whitespace). On line 6, you missed a space (b=[[x+' 'for). You can make the last line print(*map(''.join,b),sep='\n') for 1 less bytes. \$\endgroup\$
    – Artyer
    Nov 7, 2016 at 22:34

JavaScript (ES6), 238 225 215 202 196 bytes

(c,n)=>[...Array(i=n*(c=="="?4:c+1-1?2:c<"-"?n+n:n+1))].map(_=>--i%(n+(c=='/'|c>'w'||n))?c>'w'?i%n&&~-i%(n+2)?" ":c:c<'-'?i%(n*2)-n&&(~i&1|(n/2^i/n/2))?" ":c:c=="/"?i%n?" ":c:i%2?c:" ":`

Could probably be golfed, but it's a start.


Scala, 275 bytes

(i,c)=>if(c<44){val b=(" "*(i-1)+"+\n")*((i-1)/2)
b+"+ "*i+"\n"+b}else
if(c<46)"- "*i else
if(c<48)i-1 to(0,-1)map(" "*_+"/\n")mkString else
if(c<62)"= "*i+"\n"+"= "*i
else{val a=0 to i/2-1 map(x=>" "*x+"x"+" "*((i/2-x)*2-1)+"x"+" "*x+"\n")mkString;a+" "*(i/2)+"x"+a.reverse}


val f:((Int,Char)=>String)=...
print(f(10, '/'))


The code tests for the ascii value of the char to choose the right way of generating the image. The ascii values of the operators in question are: ('+' -> 43), ('-' ->45), ('/' -> 47), ('=' -> 61), ('x' -> 120)

(i,c)=>                              //define a function
  if(c<44){                            //if c is a plus
    val b=(" "*(i-1)+"+\n")*((i-1)/2)    //define the top/bottom part b as (i-1)/2 times (i-1) spaces, a plus sign and a newlineine
    b+"+ "*i+"\n"+b                      //return b, i times a plus and a space, a newline and b
  }else if(c<46)                       //if c is a '-'
    "- "*i                               //return "- " repeated i times
  else if(c<48)                        //if c is a '/'
    i-1 to(0,-1)                         //create a range from i-1 to 0 in steps of -1
    map(" "*_+"/\n")                     //map each number to that number of spaces plus a "/" and a newline
    mkString                             //join them together
  else if(c<62)                        //if c is '='
    "= "*i+"\n"+"= "*i                   //return "= " repeated i times, a newline and "= " repeated i times again
  else{                                //if c if 'x'
    val a=                               //define a, which will be the top part, as...
      0 to i/2-1                         //a range from 0 to i/2-1
      map(n=>                            //map each number n to
        " "*n                              //n spaces
        +"x"                               //plus an "x"
        +" "*((i/2-n)*2-1)                 //plus ((i/2)-n)*2-1 spaces
        +"x"                               //plus an "x"
        +" "*n                             //plus n spaces
        +"\n"                              //and a newline
      )mkString;                         //join them
    a+" "*(i/2)+"x"+a.reverse          //return a, i/2 spaces, "x" and the reverse of a 

Pip, 62 59 56 bytes

55 bytes of code, +1 for -S flag.


Note that this solution works with input of ÷ for division and * for multiplication, though it uses those characters to draw ASCII-art / and x, respectively. OP has clarified that this is okay. Try it online!


Here's a partially spaced and commented version. Note that a and b are the command-line args, i.e. the operator and the size respectively. The -S flag controls how lists are output: it joins on newlines first, but joins any nested lists on spaces.

[                 Build a list of all possible figures:
 sXbRA_AEv-_aM,b   0 - Multiplication
 (Y^aWR_Xb/2s)My   1 - Addition
 RVsX,b.a          2 - Division
 YaXbJs            3 - Subtraction
 x                 4 - Empty
 yRL2              5 - Equals
 x                 6 - Empty
] @ Aa            Index, mod 7, with ASCII value of a

And here are the individual sections:


For each row in the figure, we generate a string of spaces and then replace two of them with the input character. For row i, we want to replace the spaces at index i and b-1-i; but note that the latter can use the negative index -1-i. (It's even shorter because the variable v is preinitialized to negative 1.)

            M,b  Map this function to range(b):
sXb                Space, repeated b times
     _             Function arg
      AE           (Implicitly) convert to list and append element...
        v-_        -1 minus function arg
   RA              Replace the characters at those indices...
           a       ... with input character
                 The resulting list is output with one item per line


Using the strategy from my Draw a hollow square answer, we define a function that wraps a + in b/2 copies of its argument and returns the result as a list of characters. (Integer division // isn't necessary because the string repetition operator X automatically truncates to integer.) First, we call this function on a space, giving [" ";" ";"+";" ";" "]; then, we map the same function to that result, giving [" ";" ";"+";" ";" "] on most lines but ["+";"+";"+";"+";"+"] on the center line. This nested list is then output, because of the -S flag, with spaces between all characters on a row and newlines between rows.

                 Anonymous function:
      _Xb/2        Function arg, repeated b/2 times (implicitly rounded down)
   aWR             Wrap a in two copies of the above
  ^                Split resulting string into list of chars
 Y               Yank that function into y
(          s)    Apply function y to space
             My  Map y to that result


Each row has between b-1 and 0 spaces, followed by the input character a.

    ,b    Range(b)
  sX      Space, repeated that many times (works itemwise)
      .a  Concatenate a (itemwise)
RV        Reverse (puts the larger number of spaces at the beginning)
          Outputs newline-separated


Make a space-separated row of the input character. Save a copy for later.

 aXb    b copies of a
    Js  Join on space
Y       Yank into y (overwrites the function from earlier, but we're done using it anyway)
        This is a string, so it just gets output


The subtraction step stored half of what we need in y--just double it.

yRL2  (Implicitly) convert y to list and repeat it twice
      Outputs newline-separated

The dummy x values are there to pad the main list so that the modular indexing gives a unique index for each input character in +-*÷=.


JavaScript (ES6), 156 bytes

(c,n)=>[...Array(n--)].map((_,i,a)=>a.map((_,j)=>({'/':a=i+j-n,x:a&&i-j,'-':a=i+i-n,'+':a&&j+j-n,'=':a+2&&a-2}[c]?' ':c)).join(c=='='|c<'/'?' ':'')).join`\n`

Where \n represents the literal newline character.

  • \$\begingroup\$ In Firefox 49, I get SyntaxError: invalid property id as it's currently written, but changing the backticks around the slash to apostrophes fixed that. (Why do you have backticks there instead of apostrophes?) \$\endgroup\$ Nov 8, 2016 at 14:33
  • \$\begingroup\$ Also, the outputs for +, - and = look different than the challenge calls for: "Horizontal portions should have spaces between the characters to offset vertical/horizontal distance differences." \$\endgroup\$ Nov 8, 2016 at 14:35
  • \$\begingroup\$ @ETHproductions a) typo b) sorry, I overlooked that, will fix later. \$\endgroup\$
    – Neil
    Nov 8, 2016 at 14:39
  • \$\begingroup\$ This is ridiculously short though. I hope fixing it doesn't add too many bytes. \$\endgroup\$ Nov 8, 2016 at 14:41
  • \$\begingroup\$ @ETHproductions Thanks. I think this does at a cost of 19 bytes. \$\endgroup\$
    – Neil
    Nov 8, 2016 at 15:06

Dyalog APL, 91 86 bytes

Needs ⎕IO←0, which is default on many systems. Takes n as left argument, and one of + - × ÷ = as right argument.

t←' '⍵
s∊2 6:t[d∨⌽d∧6=s]
5=s:t[↑,/2↑¨∨/¨(⌊⍺÷2)=⍳⍺ ⍺]


    s ← ⌈ ⍎ ⍕ 3 ⍵ 2             ⍝ calculate ceil(3 f 2), where f is the given symbol
    t ← ' '⍵                    ⍝ create a string with a space before the symbol
    d ← ⌽ ∘.=⍨ ⍺                ⍝ Boolean \ diagonal
    s ∊ 2 6: t[d ∨ ⌽ d ∧ 6 = s] ⍝ if ÷ or × index t with one or both diagonals
⍝ find coordinates that are in the middle of at least one dimension
⍝ pad with zeros for spacing
⍝ use that to index into t
    5 = s: t[ ↑ ,/ 2↑¨ ∨/¨ (⌊ ⍺ ÷ 2) = ⍳ ⍺ ⍺]
⍝ - or =:
    (2 - s) (2 × ⍺) ⍴ t       ⍝ one or two rows of double-spaced symbols

Mathematica, 191 bytes

e=#~Mod~2==1&;StringRiffle[Normal@SparseArray[{a_,b_}/;(a+b==d+1||a==b)[e@b&&a<3,,e@b&&(a==⌈d/2⌉||b==d),,e@b&&a<2,,a+b==d+1][[Last@ToCharacterCode@#~Mod~10]]:>#,{d=#2,2d-1}," "],"
"," "]&

Anonymous function. Takes a string and a number as input, and returns a string as output. Not the shortest by far, but still fun to write.


C, 396 bytes

#define p(x) printf(x);
i,j,k,m;f(char s,int n){i=k=0;if(s==45)for(;i<n;++i)p("- ")m=n/2;if(s==43)for(;i<n;++i)for(j=0;j<=m;++j)if(i-m)p(j-m?"  ":"+\n")else{for(;k<n;++k)p("+ ")p("\n")j+=m;}if(s==61)for(;i<2;++i){for(k=0;k<n;++k)p("= ")p("\n")}j=n;if(s==47)for(;i<n;++i){--j;for(k=0;k<j;++k)p(" ")p("/\n")}if(s==120)for(;i<n;++i){k=m-abs(m-i);for(j=0;j<n-k;++j)p(j-k?" ":"x")p(i-m?"\bx\n":"\n")}}

Call with:

int main()
   f('x', 5);
   return 0;

SOML, 104 100 bytes (non-competing)

    Cd³³b»E +=?ce*d+e{t}bd*Oe{t}} ==?b*tt} -=?b*t} /=?bc*b{j:d+p}} x=?"”cb*e{jj⁴⁴d;d+++tGG;c+;}XOdoe{O

This is kind-of competing as I'm pretty sure that everything I used here has docs on github before this questions posting date but the parser doesn't have support for some functions I used so idk.


PHP, 306 292 281 282 281 275 270 bytes

$r=str_pad("",2*$n=$argv[2],($c=$argv[1])." ")."\n";if(",">$c)$r=($m=str_repeat(str_pad($c,$n," ",0)."\n",$n/2))."$r$m";if(9<$c)$r.=$r;if(w<$c)for($r=$c;$i<$n;$r[$i*(2+$n)]=$r[++$i*$n-1]=x)$r[$i*$n+$i+$n]="\n";if("/"==$c)for($r=$s="";$i++<$n;$s.=" ")$r="$s/\n$r";echo$r;

Ooh this is bulky ... needs further golfing.
I could save 4 bytes with physical linebreaks or one byte with putting "\n" into a variable.

  • 1
    \$\begingroup\$ Nice.for the "+", I think you need to match the height and not always 3. Also you should be able golf more to use if() instead of case/break; \$\endgroup\$
    – Crypto
    Nov 9, 2016 at 7:50

C#, 744 Bytes

It's like 1 million characters long, I think, but I don't care, I am just so happy that I solved this...


string A(string s,int n){string O="";Func<string,int,string>R=(a,b)=>{return string.Join("",Enumerable.Repeat(a,b))+"\r\n";};switch(s){case"+":for(int i=0;i<n;i++){if(i==n/2){O+=R("+",n);}else{O+="+".PadLeft(n-n/2,' ').PadRight(n-n/2,' ')+"\r\n";}}return O;case"=":return R("=",n)+R("=",n);case "-":return R("-",n);case "/":for(int i=n;i>0;i--){O+="/".PadLeft(i)+"\r\n";}return O;case "x":int x=0;string[]r=new string[n];for(int i=n;i>0;i--){if(n-x-x<0){O+="x".PadLeft(x+1)+"\r\n";break;}string row=string.Join("",Enumerable.Repeat(" ",x))+"x"+string.Join("",Enumerable.Repeat(" ",n-x-x))+"x"+"\r\n";O+=row;x++;r[x]=row;if(i==n/2)break;}for(int i=r.Length-1;i>0;i--){if(string.IsNullOrEmpty(r[i]))continue;O+=r[i];}return O;default:return "";}}


public string A(string s, int n)
  string O = "";

  Func<string, int, string> R = (a, b) =>
    return string.Join("", Enumerable.Repeat(a, b)) + "\r\n";

  switch (s)
    case "+":
      for (int i = 0; i < n; i++)
        if (i == n / 2)
          O += R("+", n);
          O += "+".PadLeft(n - n / 2, ' ').PadRight(n - n / 2, ' ') + "\r\n";
      return O;
    case "=":
      return R("=", n) + R("=", n);
    case "-":
      return R("-", n);
    case "/":
      for (int i = n; i > 0; i--)
        O += "/".PadLeft(i) + "\r\n";
      return O;
    case "x":
      int x = 0;
      string[] r = new string[n];
      for (int i = n; i > 0; i--)
        if (n - x - x < 0)
          O += "x".PadLeft(x + 1) + "\r\n";
        string row = string.Join("", Enumerable.Repeat(" ", x))
          + "x"
          + string.Join("", Enumerable.Repeat(" ", n - x - x)) + "x" + "\r\n";
        O += row;
        r[x] = row;
        if (i == n / 2)
      for (int i = r.Length - 1; i > 0; i--)
        if (string.IsNullOrEmpty(r[i]))
        O += r[i];
      return O;
      return "";


+: 3, 5, 7, 9, 11
/: 7, 8, 9, 10
-: 3, 4, 5, 6
=: 3, 4, 5, 6, 7
x: 5, 7, 9, 11

Too much to paste and format here, I created a pastebin:


  • \$\begingroup\$ Please golf it and provide a byte count. \$\endgroup\$
    – mbomb007
    Nov 10, 2016 at 19:29

C, 331 Bytes

if(43==o)for(i=n;i--;puts("")){for(j=n;j--;printf(i==n/2||!j?"+ ":" ")){}}

The operator is passed as ASCII code into o and the character count into n. I only added spaces between horizontally consecutive characters into the plus sign, since this was the only one where the output would have been distorted if I hadn't and in the task it only said "should". I use two nested loops counting down (except for - where I only need one line).

= Three Lines, one of them empty, straight forward

+ using printf because of the spaces

- straight forward

/ have the inner loop print at zero and start at the outer loop's counter

x have the inner loop print at the outer loop's counter and its "inverse" n-i. Still need to look at why I'am off-by-one here.

Sample call:

#include <stdio.h>
/*  =       61
    +       43
    -       45
    /       47
    Space   32
    x       120
int main(int argc, char **argv){
    printf("%s\n%s\n",argv[1], argv[2]);

Lua, 402 344 312 bytes


r,p,b,x=string.rep,print,' ','x'function d(s,n)h,l=(n+1)/2,s..b;e=r(l,n)if s=='-'then p(e)elseif s=='='then p(e)p(e)else for f=1,n do p(s=='/'and(r(b,n-f)..s)or s=='+'and(f~=h and r(' ',n-1)..'+'or r('+ ',n))or f<h and r(b,f-1)..x..r(b,n-2*f)..x or f>h and r(b,n-f)..x..r(b,2*f-2-n)..x or r(b,f-1)..x)end end end


r,p,b,x=string.rep,print,' ','x'function d(s,n)h,l=(n+1)/2,s..b;e=r(l,n)if s=='-'then p(e)elseif s=='='then p(e)p(e)else for f=1,n do if s=='/'then p(r(b,n-f)..s)elseif s=='+'then p(f~=h and r(' ',n-1)..'+'or r('+ ',n))elseif s=='x'then p(f<h and r(b,f-1)..x..r(b,n-2*f)..x or f>h and r(b,n-f)..x..r(b,2*f-2-n)..x or r(b,f-1)..x)end end end end


r,p,b,x=string.rep,print,' ','x'function d(s,n)h=(n+1)/2;if s=='-'then p(r(s..b,n))end;if s=='='then p(r(s..b,n))p(r(s..b,n))end;if s=='/'then for i=1,n do p(r(b,n-i)..s)end end;if s=='+'then for i=1,n do p(i~=h and r(' ',n-1)..'+'or r('+ ',n))end end;if s=='x'then for i=1,n do if i<h then p(r(b,i-1)..x..r(b,n-2*i)..x)elseif i>h then p(r(b,n-i)..x..r(b,-n+2*i-2)..x)else p(r(b,i-1)..x)end end end end

90 characters reduced and it's now painful to look at even when expanded. :|


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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