# Operator ASCII art

### Challenge

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.

### Input

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.

### Output

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.

### Rules

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

### Examples

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     x

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

## Pip, 6259 56 bytes

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

[sXbRA_AEv-_aM,b(Y^aWR_Xb/2s)MyRVsX,b.aYaXbJsxyRL2x]@Aa


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!

### How?

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

Multiplication

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

sXbRA_AEv-_aM,b
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.

(Y^aWR_Xb/2s)My
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


Division

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

RVsX,b.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


Subtraction

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

YaXbJs
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


Equals

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 +-*÷=.

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

Ç=ü-/Àé X
ç^Ó/é Àä$ç+/ÀÄM|ÀR+ ç=/Ä ç¯/lòhYpX çx/rxòl3Äjxlrx  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.

# Explanation

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'  • so is that what multiple lines are used for? – Conor O'Brien Nov 8 '16 at 12:48 • @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 – DJMcMayhem Nov 8 '16 at 14:09 # 05AB1E, 81767473706968656462605957 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. Code: Ç6&"¹s<ú.s.Bívy¹'xQiÂðñ}, ¹×S)»¹'=Qƒ= ;ƒ¹})D¦»»Rû.c"#è.V  Or in a more readable form:  Ç6& "¹s<ú.s.Bívy¹'xQiÂðñ}, ¹×S)»¹'=Qƒ= ;ƒ¹})D¦»»Rû.c" #è.V  Uses the CP-1252 encoding. Try it online! • Here we go again... :P – DJMcMayhem Nov 7 '16 at 17:53 • @DrMcMoylex Hahaha, good old times :). – Adnan Nov 7 '16 at 17:53 • More readable... totally... – Oliver Ni Nov 7 '16 at 17:56 • For a given definition of "readable". – Matt Lacey Nov 8 '16 at 22:23 • – DLosc Nov 10 '16 at 16:01 # Python 3, 304283 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! t,s=input().split() s=int(s) r=range(s) 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] print(*map(''.join,b),sep='\n')  • 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). – Kade Nov 7 '16 at 17:25 • 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 – Rod Nov 7 '16 at 17:31 • Yes, trailing spaces/newlines are acceptable. – Yodle Nov 7 '16 at 17:41 • 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. – Artyer Nov 7 '16 at 22:34 # JavaScript (ES6), 238225215202 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:" ": ).join  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}  Usage: val f:((Int,Char)=>String)=... print(f(10, '/'))  Explanation: 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 }  ## 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. • 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?) – ETHproductions Nov 8 '16 at 14:33 • 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." – ETHproductions Nov 8 '16 at 14:35 • @ETHproductions a) typo b) sorry, I overlooked that, will fix later. – Neil Nov 8 '16 at 14:39 • This is ridiculously short though. I hope fixing it doesn't add too many bytes. – ETHproductions Nov 8 '16 at 14:41 • @ETHproductions Thanks. I think this does at a cost of 19 bytes. – Neil Nov 8 '16 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. {s←⌈⍎⍕3⍵2 t←' '⍵ d←⌽∘.=⍨⍺ s∊2 6:t[d∨⌽d∧6=s] 5=s:t[↑,/2↑¨∨/¨(⌊⍺÷2)=⍳⍺ ⍺] (2-s)(2×⍺)⍴t}  ### Explanation { 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, 306292281282281275 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.

• 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; – Crypto Nov 9 '16 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...

Golfed:

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 "";}}


Ungolfed:

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


Testing:

+: 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:

Pastebin

• Please golf it and provide a byte count. – mbomb007 Nov 10 '16 at 19:29

## C, 331 Bytes

i,j;f(o,n){if(47==o)for(i=n;i;puts("")){for(j=i--;j--;putchar(j?32:o)){}}
if(43==o)for(i=n;i--;puts("")){for(j=n;j--;printf(i==n/2||!j?"+ ":" ")){}}
if(45==o)for(i=n;i--;putchar(o)){}
if(61==o)for(i=3;i--;puts("")){for(j=n;j--;putchar(i&1?32:o)){}}
if(120==o)for(i=n;i;puts("")){for(j=0;j++<n;putchar(j==i||j==n-i+1?o:32)){}i--;}}


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]);
f(*argv[1],strtol(argv[2],NULL,10));
}


# Lua, 402344 312 bytes

312:

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


344:

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


402:

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