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

## 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 '18 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 '18 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 '18 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 '18 at 13:28
• @JacobGarby: My argument was stylistic, not golfy :) Jul 25 '18 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 '18 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 '18 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 '18 at 13:19
• Did someone say Rotate? That gives me an idea...
– Neil
Jul 24 '18 at 17:06
• @Neil hey, you got quite an improvement there! :-) Jul 25 '18 at 8:25

# 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 '18 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 '18 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 '18 at 11:43
• You can also store q.join in a variable to save a byte
– Rod
Jul 23 '18 at 11:48
• 217. Joined all the q.joins, and a couple of other things
– Jo King
Jul 23 '18 at 12:46

# 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 '18 at 10:45
• Nice, it gets n=0 right too Jul 23 '18 at 10:50

# 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


# 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 '18 at 20:45
• Though then inlining is one byte shorter. Jul 24 '18 at 20:46
• Jul 24 '18 at 20:50
• 321 bytes Sep 23 '19 at 7:03

# 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[1],C,s[2]);
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 '18 at 4:27
• @ceilingcat The undefined evaluation order of function arguments give me pause. Jul 27 '18 at 17:11

# 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[0][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[0]=t[v]=t[j]=P;t=s[k-r];t[0]=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 '18 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 '18 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 '18 at 17:13

# 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[1]).'^
';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 '18 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 '18 at 16:23
• Oh, and $i>0 and $m>0 can be written simply as $i and $m. Jul 25 '18 at 17:33
• With trailing spaces, as in some other solutions. Jul 25 '18 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 '18 at 11:37

# 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[0][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[0][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 '18 at 5:26
• 307 bytes: Try it online! Jul 24 '18 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 '18 at 11:07
• In Python 2, input() automatically eval()s the string, so you can skip the int() call as well. Jul 24 '18 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 '18 at 15:45