# Draw the "Cool S"

## Introduction

We all know the cool S (also known as Superman S, Stüssy S, Super S, Skater S, Pointy S, Graffiti S etc. etc.): billions of schoolchildren around the world drew this S and immediately felt proud of themselves. In case you've forgotten or had a completely uncool childhood, here is an image of said cool S: Given a scale factor n as input (where $1\leq n\leq 20$), output the Cool S in ASCII art.

## How to Draw It ## Output

The Cool S when n = 1 is:

   ^
/ \
/   \
/     \
|  |  |
|  |  |
\  \  /
\  \/
/\  \
/  \  \
|  |  |
|  |  |
\     /
\   /
\ /
v


And for different values of n, you simply make the output n times bigger. For example, n=2:

     ^
/ \
/   \
/     \
/       \
/         \
|    |    |
|    |    |
|    |    |
|    |    |
\    \    /
\    \  /
\    \/
/\    \
/  \    \
/    \    \
|    |    |
|    |    |
|    |    |
|    |    |
\         /
\       /
\     /
\   /
\ /
v


Note that the vertical sections are two times longer and the spacing between the vertical lines is two times wider.

And when n=3:

       ^
/ \
/   \
/     \
/       \
/         \
/           \
/             \
|      |      |
|      |      |
|      |      |
|      |      |
|      |      |
|      |      |
\      \      /
\      \    /
\      \  /
\      \/
/\      \
/  \      \
/    \      \
/      \      \
|      |      |
|      |      |
|      |      |
|      |      |
|      |      |
|      |      |
\             /
\           /
\         /
\       /
\     /
\   /
\ /
v


Note: Although not required, your code may also be able to support n=0:

 ^
/ \
\\/
/\\
\ /
v


## Winning

The shortest program in bytes wins.

• Related: Draw an S-Chain Jul 23, 2018 at 9:31
• The ASCII-building 90's kid in me wants to suggest using /\ instead of ^ for the tip. Looks cleaner that way, plus it maintains the same slope inclination :) Jul 25, 2018 at 12:16
• @Flater only problem is that /\ uses two characters, so the central vertical line would have to be offset which makes it look very untidy Jul 25, 2018 at 13:21
• @BetaDecay: It looks fine on N=2 and N=3 (since it retains point symmetry), but I agree for N=1. There's also the option of the upside down V: Λ Jul 25, 2018 at 13:28
• @JacobGarby: My argument was stylistic, not golfy :) Jul 25, 2018 at 14:14

# Charcoal, 58 53 47 43 41 bytes

Ｎθ≔⊕⊗θδ↗θ/⊗θ↘δ^‖Ｂ↓‖Ｍ← vＭδ⁰⊗θ↗⊕θＭ⁰δ↗θ/⊗θ⟲Ｔ


Try it online!

I just wanted to try another approach, this draws the outside via reflections (thanks to Neil for expanding the idea) and then draws the inside part. As Charcoal has :Left as default direction to draw lines, I make use of that direction as much as possible to save some bytes by drawing the S horizontally, like this:

     /----\    /----\
/      \  /      \
/        \/        \
/         /          \
/         /            \
v     ----/    /----     ^
\            /         /
\          /         /
\        /\        /
\      /  \      /
\----/    \----/


And then I just need to rotate the canvas 90 degrees counterclockwise.

• You may be onto something there... 22 bytes gets you all of the outside...
– Neil
Jul 23, 2018 at 12:49
• @Neil it wasn't exactly like that, your idea needed a minor fix, but indeed this has been a great improvement! Jul 23, 2018 at 13:11
• Yeah I made a similar mistake on my original post because I didn't check the effect of scaling correctly.
– Neil
Jul 23, 2018 at 13:19
• Did someone say Rotate? That gives me an idea...
– Neil
Jul 24, 2018 at 17:06
• @Neil hey, you got quite an improvement there! :-) Jul 25, 2018 at 8:25

# Charcoal, 4742 41 bytes

Ｆv^«↓⊗θ↘⊗⊕θ←↓⊗θ↙⊕⊗θ↖ι↖⊕⊗θ→↑⊗θ↗⊕θＭθ⁺⊗θ⊕θ⟲⁴


Try it online! Link is to verbose version of code. Explanation: Draws the following lines in order:

   ^
/ \
/   \
/     \
|  1  |
|  1  |
\  2  /
\  2/
8\  2
8  \  2
7  |  3
7  9  3
6     4
6   4
6 4
5


Where 5 is the current character of the string v^. At the end of the first loop the cursor is then positioned at point 9. The entire canvas is then rotated so that the other half of the Cool S can be drawn. (The canvas actually gets rotated twice, but this is just an implementation detail.)

Charcoal doesn't support RotateCopy(:Up, 4) but if it did then this would work for 33 bytes:

↖^↖⊕⊗θ→↑⊗θ↗⊕θ‖ＢＭ↓↙⊗θ→↓⊗θ⟲Ｃ↑⁴Ｊ⁰¦⁰v

– Neil
Jul 23, 2018 at 10:45
• Nice, it gets n=0 right too Jul 23, 2018 at 10:50

# Python 3, 255249248 209 bytes

-6 bytes thanks to Kevin Cruijssen

-1 byte thanks to Kevin Cruijssen

-39 bytes thanks to Rod and Jo King

n=int(input())
m=2*n
a,b,q,c,l='\ \n/|'
f=m*b
s=q+q.join([f[d:]+c+b*2*d+b+a+f[d:]for d in range(m+1)]+[l+f+l+f+l]*m+[d*b+a+f+a+f[d*2:]+c+d*b for d in range(n)]+[n*b+a+f+a+c+n*b])
print(f,'^'+s+q+s[::-1]+f,'v')


Try it online!

It now handles n=0.

• Both o+~d can be m-d and range(o) can be range(m+1), and then you can remove o=m+1\n to save 6 bytes. Nice answer though, +1 from me. Jul 23, 2018 at 11:05
• Oh, and one more byte by changing p(s)\np(s[::-1]) to p(s+q+s[::-1]): 248 bytes Jul 23, 2018 at 11:13
• You can save 6 bytes if you use a single print, and more 4 by removing [] from join([...]), totalizing 238 bytes
– Rod
Jul 23, 2018 at 11:43
• You can also store q.join in a variable to save a byte
– Rod
Jul 23, 2018 at 11:48
• 217. Joined all the q.joins, and a couple of other things
– Jo King
Jul 23, 2018 at 12:46

# Canvas, 3632 29 bytes

«|＊‼ｌ├／Ｌ１^╋；╶╵＼∔∔│α╶«├：╵╋：↔↕∔


Try it here!

A whole lot of stack manipulation. (outdated) explanation:

«|*                                an array of input*2 "|"s
‼                               cast to a 2D object (needed because bug)
:                              duplicate that (saved for the center line)
l├                            height+2
/                           create a diagonal that long
L1^╋                       and in it, at (width; 1) insert "^"
;∔                     append the vertical bars
^
/
so far done:       /
/
|
|
⁸╵                   input+1
\                  antidiagonal with that size
∔                 appended to the above
│                mirror horizontally
^
/ \
/   \
/     \
current:   |     |
|     |
\     /
\   /                                                       |
α               get the 2nd to last popped thing - the antidiagonal  |
└∔             append it to the vertical line copied way before:    \
⁸«├          input/2 + 2                                            \
:╵        duplicate + 1
╋       at (input/2 + 2; input/2 + 3) in the big part insert  ^
:↔↕∔   mirror a copy vertically & horizontally and append that to the original


# C (gcc), 260 254 bytes

-6 bytes thanks to ceilingcat.

f(n){int s=2*n++,t=s+1,I[]={1,t,s,n,n,s,t,1},A[]={s,1,1,1,2*t,1,t,t,1,t,1,n,t,t,1,t,t,1,1,1,t,s,1,1},x;for(s=8;s--;)for(n=0;n<I[s];n++,puts(""))for(t=3;t--;)x=s*3+t,printf("%*c",n*("AAAA?BAAAAC@?ABAAACA@AAA"[x]-65)+A[x],"w!!!0]}}}]]00]]}}}]!0_!!"[x]-1);}


Try it online!

## Rundown

We can divide the shape into parts:

 ^           Top cap
/ \          Top slope
|||          Sides
\\/          Twist, part 1
/\\          Twist, part 2
|||          Sides
\ /          Bottom slope
v           Bottom cap


Each part could be described by a number of lines, three chars, and three relationships to certain values that decides the field-width at each line.

A first iteration came to be:

#define g(x,s,A,B,C)for(i=0;i<x;i++)printf("%*c%*c%*c\n",A,*s,B,s,C,s);
f(n)
{
int s=2*n++,t=s+1,i;

g(1,  "  ^",  1,      1,  t-1)
g(t, "/ \\",t-i,      1,2*i+1)
g(s,  "|||",  1,      t,    t)
g(n,"\\\\/",i+1,      t,t-2*i)
g(n,"/\\\\",n-i,  2*i+1,    t)
g(s,  "|||",  1,      t,    t)
g(t, "\\/ ",i+1,2*t-2*i,    1)
g(1,  "  v",  1,      1,  t-1)
}


The calls to the g() macro looks very much like a table could be constructed and looped over. Field-widths are sometimes related to the index counter, and sometimes not. We can generalise the field-width to be F * i + A, where F is some factor to multiply i with, and A is some value to add to the width. So the last width of the fourth call above would be -2 * i + t, for example.

Thus we get:

f(n){int s=2*n++,t=s+1,         s = size of "side" parts, t = size of top and bottom slopes
I[]={1,t,s,n,n,s,t,1},          The number of lines per part.
A[]={...},x;                    A[] holds the values to add to each field-width.
for(s=8;s--;)                   Loop through the parts.
for(n=0;n<I[s];n++,puts(""))    I[s] decides how many lines to the part. Ends with newline.
for(t=3;t--;)                   Go through the three chars of each line.
x=s*3+t,                        Calculate offset.
printf("%*c",                   Print the char.
n*("..."[x]-65)+A[x],           Build field-width. The string holds the index factor, A[]
holds the offset part.
"..."[x]-1);}                   The char itself is grabbed from the string.
Shifted by 1 to eliminated double backspaces.


In the end it was not much shorter than a tightened version of the g() calling one, but shorter is shorter.

• @ceilingcat Cheers. Jul 27, 2018 at 4:27
• @ceilingcat The undefined evaluation order of function arguments give me pause. Jul 27, 2018 at 17:11
• for(n=-1;++n<I[s];puts("")) saves a byte. Feb 9, 2022 at 23:42
• Building on @veqtrus 252 bytes Feb 12, 2022 at 19:46

# Python 2, 227208207202196 181 bytes

I=n=2*input()
R,L,S,P='/\ |'
k=n*[2*(P+S*n)+P]
exec"k=[R+S+2*S*I+L]+k+-~I%2*[L+S*n+L+S*I+R];I-=1;"*-~n
print'\n'.join(t.center(2*n+3)for t in['^']+k+[a[::-1]for a in k[::-1]]+['v'])


Try it online!

Thks to Jo King for 1 byte; and then another 5 bytes total (via n => 2*n).

Works for n=0 as well.

# C (gcc), 379353344 334 bytes

I used a couple of #defines for subexpression elimination and several globals to communicate between the internal functions. The main loop goes {0,1,2,3,3,2,1,0} to construct the S.

Thanks to Jonathan Frech for the suggestions.

#define z(a,b...)printf("%*c%*c%*c\n"+a,b);}
#define y(a){for(i=~-a*t;v*i<v*a*!t+t;i+=v)
i,n,p,r,t,u,v;a(){z(6,r+2,94+t*24)b()y(-~r)z(3,-i-~r,47+u,i*2+2,92-u)c()y(r)z(0,~r,124,~r,124,~r,124)d()y(-~n)z(0,i+1,92-u,2*(n-t*i)+1,92,2*(n-!t*i)+1,47+u)(*x[])()={a,b,c,d};f(s){r=2*s;for(p=0;p<8;x[7*t-p++*(2*t-1)](n=s))t=p>3,v=2*!t-1,u=t*45;}


Try it online!

• w -r-1 could possibly be golfed to w~r. Jul 24, 2018 at 20:45
• Though then inlining is one byte shorter. Jul 24, 2018 at 20:46
• Jul 24, 2018 at 20:50
• 307 bytes Feb 14, 2022 at 6:28

# PHP, 378374378377376335331 328 bytes

-3 bytes, thanks to manatwork

-41 bytes, thanks to manatworks' suggestions

-1 byte, merged two increments into a +=2

-1 byte, removed superfluous \

-4 bytes by echoing once. Forgot I needed to pass the string into the function so this is more bytes

Works for n = 0 as well.

function s($b){return str_pad($w,$b);}echo s($i=1+$a=2*$argv).'^
';for(;$i;$j++,$y=$z.$y)echo$z=s(--$i).'/'.s(++$j).'\
';for(;$k<$a;$k++)$x.='|'.s($a).'|'.s($a).'|
';echo$x;for(;$l<=$a/2;)echo s($m++).$c='\\',s($a).$c.s($a-$l++*2).'/ ';for(;$m;$n+=2)echo s(--$m).'/'.s($n).$c.s($a).'\ ';echo$x.strtr($y,'/\\','\/').s($a+1).v;


Try it online!

• As function declaration is quite expensive and you use t() only twice, would be shorter without it. If beside the 9 notices you take 1 warning too, you can remove the quotes around 'v' in the final echo. Jul 25, 2018 at 16:02
• You could use single loop for the top and bottom oblique parts. The initialization of $a and$i could be compacted by moving them at their first usage. Jul 25, 2018 at 16:23
• Oh, and $i>0 and $m>0 can be written simply as $i and $m. Jul 25, 2018 at 17:33
• With trailing spaces, as in some other solutions. Jul 25, 2018 at 20:00
• You can also move the declaration of $c to its first usage. Just change the . concatenation after it to ,. Try it online! Jul 26, 2018 at 11:37 # Java, 435 bytes The function itself takes 435 bytes. There is certainly room for improvement, "high level" by analyzing the rules about where to place which character (in the end the S is point-symmetric), and "low-level", by classical golfing (maybe pulling out another variable or combining two of the for-loops). But it's a first shot with this rather ungolfy language: import static java.util.Arrays.*; import static java.lang.System.*; public class CoolS { public static void main(String[] args) { print(1); print(2); print(3); } static void print(int n){int i,r,d=3+6*n,w=3+n*4,h=6+n*10,m=n+n,v=w/2,k=h-1,j=w-1;char t[],S='/',B='\\',P='|',s[][]=new char[h][w];for(char x[]:s)fill(x,' ');s[v]='^';s[k][v]='v';for(i=0;i<1+m;i++){r=i+1;t=s[r];t[v-r]=S;t[v+r]=B;t=s[k-r];t[v-r]=B;t[v+r]=S;}for(i=0;i<m;i++){r=2+m+i;t=s[r];t=t[v]=t[j]=P;t=s[k-r];t=t[v]=t[j]=P;}for(i=0;i<1+n;i++){r=2+m+m+i;t=s[r];t[i]=t[i+1+m]=B;t[j-i]=S;t=s[d-i];t[i]=S;t[v-i]=t[j-i]=B;}for(char x[]:s)out.println(x);} }  • Hi there. Imports are part of the byte-count I'm afraid, so your current answer is actually 478 bytes. You can however golf it down to (coincidentally enough) your current 435 bytes with some basic things to golf. Jul 31, 2018 at 7:15 • Been able to golf a bit more to 405 bytes by removing some variables and using t=... a bit less where it would save bytes. If you have any questions about any of the changes I made, let me know. :) Jul 31, 2018 at 7:33 • Thanks @KevinCruijssen , unfortunately I currently cannot invest more time here - this was just a recreational thing, and considering the "verbosity" of Java, not a serious competitor anyhow ;-) Consider adding your solution as an own answer, though - then we at least have some intra-language competition :-) Aug 1, 2018 at 17:13 # ><>, 1024 bytes i'0'-i1+:?!v1-'0'-$a*+1v
v          <           <
>~     :1-2*3+ >1-' 'v       v                                             oa&0~~~<
v&1:oa*2:~o'^'^?:o  <                                              >~'/'o$:v <^ < >>' 'o1-: ?v v >@ '\'o$v v   -1o<           >          v >:?vv^ -1<     ^     <
:^         <   ~                  ~>      \:>:?v       v  >'/'v^o' '^!?:-1<:<  > ' 'o^ >'\'o:1-?v^
- vo' '<:&o'/' < <                ^^?:o' '\  \ >' '/'\'\~$^ > o:?v~1>$  :?v$^ ~! oa$+2$-1 < ^1\1-:?^~'\'oao v / \-1<:@@~o/o1- v^a< >1+^v:$-2<vo'\'<      ^@~<v             <
v^?:+1v!?:-1&+2/            /   /        \        \' '^!?:<         <     >$@@:>1-' 'o:?v^ >~'\'o$v^    oa<
>         ^     /-1   /-1 /        \        \       \:0:<                ^        <   v      -1< :v o' '<^ +1$-2 < v -1< >~&~1& >:2*:1->'|'o1>@@:>' 'o1-:?^~@'|'o:?^~ao: ?^~&?^ 1+2*0 >:>:?!^' 'o^ >>1-: ?^~'/'o:2-?^@@2*ao>' 'o:?^'v'o ;  Takes one number 1-99 as input and draws the Cool S. The program uses only one stack to store the number of spaces. It is almost not golfed, coded just for practice and fun :D Try it online! • Welcome to the site, and nice first answer! Since the question specifies that scale factors up to 20 must be supported, you'll need to modify your answer to allow 2-digit inputs. I think it shouldn't be too hard, given what you've already accomplished. :) Feb 10, 2022 at 19:09 • @DLosc Сhanged. Feb 10, 2022 at 19:40 # Python 3, 321 307 bytes Thanks to @EsolangingFruit for saving 14 bytes n=int(input()) b,f='\/' c,l=4*n+3,10*n+6 r=range h=c//2 L=[c*[' ']for _ in r(l)] L[h],L[-1][h]='^v' for i in r(h):a=L[h-i];a[i],a[c+~i]=f,b for i in r(2*n):L[h-~i][0::h]='|'*3 for i in r(n+1):a=L[h+h+i];a[c+~i],a[i:c-1:h]=f,b*2 for i in r(1,l//2):L[l+~i]=L[i][::-1] print('\n'.join(''.join(i)for i in L))  Try it online! # Python 2, 303 bytes n=int(input()) b,f='\/' c,l,r=4*n+3,10*n+6,range h=c/2 L=[c*[' ']for _ in r(l)] L[h],L[-1][h]='^v' for i in r(h):a=L[h-i];a[i],a[c+~i]=f,b for i in r(2*n):L[h-~i][0::h]='|'*3 for i in r(n+1):a=L[h+h+i];a[c+~i],a[i:c-1:h]=f,b*2 for i in r(1,l/2):L[l+~1]=L[i][::-1] print'\n'.join(''.join(i)for i in L)  Try it online! • You can replace '\\','/' on the second line with *'\/' to save three bytes. Jul 24, 2018 at 5:26 • 307 bytes: Try it online! Jul 24, 2018 at 5:36 • Thanks! @EsolangingFruit! I was not aware of bit operations in Python. Also, it would save a few bytes to use Python2 because of the division and parentheses in print Jul 24, 2018 at 11:07 • In Python 2, input() automatically eval()s the string, so you can skip the int() call as well. Jul 24, 2018 at 15:42 • For Python 3, you can change the last line to for l in L:print(*l,sep="") (I don't think there is an equivalent in Python 2). Jul 24, 2018 at 15:45 # Regenerate, 180 bytes ( {2*$~1}) ^\n(( {#3-1}|$1)/($4| )\\\n){#1+1}((\|$1\|$1\|\n){#1})(( $8|)(\$1\\)( {#10-2}|1)/\n){~1+1}(( {#12-1}|8)/( 13|)9\n){~1+1}5(( 15|)\$${#16-2}|4)/\n){#1+1}1 v  Takes input as a command-line argument. Try it here! ### Explanation Hoo boy, this is long. It's not actually super-complicated, though; once you get a few basic principles of golfing in Regenerate, this just uses the same techniques over and over. ( {2*~1})  Group 1: Take the command-line argument (~1), multiply it by 2, and add that many spaces.  ^\n  Complete the first line with one more space, ^, and a newline. (...){#1+1}  Group 2 generates one line of the / \ section. Repeat it (length of group 1, plus 1) times. It contains groups 3 and 4. ( {#3-1}|1)/  Group 3: Add spaces, one fewer than the last time we matched group 3; or, if group 3 hasn't been matched before, start with the contents of group 1 (arg * 2 spaces) instead. After group 3, add a forward slash. ( 4| )\\\n  Group 4: Add spaces, two more than the last time we matched group 4; or, if group 4 hasn't been matched before, start with one space instead. After group 4, add a backslash and a newline. ((\|1\|1\|\n){#1})  Group 5 is the whole vertical lines section, which we're capturing because we can reuse it verbatim later. Specifically, this is (length of group 1) repetitions of group 6, which consists of: pipe, group 1, pipe, group 1, pipe, newline. (...){~1+1}  Group 7 generates one line of the \ \/ section. Repeat it (argument plus 1) times. It contains groups 8, 9, and 10. ( 8|)  Group 8: Add spaces, one more than the last time we matched group 8; or, if group 8 hasn't been matched before, start with empty string instead. (\$1\$$  Group 9: backslash, group 1, backslash (capture for reuse later). ( {#10-2}|$1)/\n


Group 10: Add spaces, two fewer than the last time we matched group 10; or, if group 10 hasn't been matched before, start with the contents of group 1 instead. After group 10, add a forward slash and a newline.

(...){$~1+1}  Group 11 generates one line of the /\ \ section. Repeat it (argument plus 1) times. It contains groups 12 and 13. ( {#12-1}|$8)/


Group 12: Add spaces, one fewer than the last time we matched group 12; or, if group 12 hasn't been matched before, start with the most recent contents of group 8 instead. After group 12, add a forward slash.

(  $13|)$9\n


Group 13: Add spaces, two more than the last time we matched group 13; or, if group 13 hasn't been matched before, start with empty string instead. After group 13, add the contents of group 9 (two backslashes with some spaces in between) and a newline.

$5  Add the contents of group 5 again (vertical pipes section). (...){#1+1}  Group 14 generates one line of the \ / section. Repeat it (length of group 1, plus 1) times. It contains groups 15 and 16. ($15|)\\


Group 15: Add spaces, one more than the last time we matched group 15; or, if group 15 hasn't been matched before, start with empty string instead. After group 15, add a backslash.

( {#16-2}|$4)/\n  Group 16: Add spaces, two fewer than the last time we matched group 16; or, if group 16 hasn't been matched before, start with the most recent contents of group 4 instead. After group 16, add a forward slash and a newline. $1 v


For the last line, add the contents of group 1, a space, and v.

• Oh, I like Regenerate, But Is there a way to add two numbers in Regenerate? Feb 10, 2022 at 0:14
• @Fmbalbuena Yep Feb 10, 2022 at 5:13

# C (gcc), 271261253 230 bytes

-10 bytes by moving 2* inside S macro

-8 bytes by placing u,d in the global scope and replacing (n-u) with d

-23 bytes by abusing the C preprocessor, thanks to @ceilingcat

#define S(i,c)printf("%*s"#c,2*i,"");
#define R(m)}for(u=0,d=n*m+1;d--;u++){S(0+
#define V(x,y)S(x,\\\n)R(2-1)0,|)S(n,|)S(n,|\n)R(y)u,\\)S(
u,d;f(n){{S(n+1,^\n)R(2)d,/)V(u+1,1)n,\\)S(d,/\n)R(1)d,/)S(u,\\)V(n,2)d+1,/\n)}S(n+1,v\n)}


Try it online!

# VyxalC, 49 bytes

\^?d›(\/n꘍øM)\|?꘍m∞?dḊ?›(\\?꘍m?›n-d꘍\/J)W:ṘRJṪ\vJ


Try it Online!