# 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 – Kevin Cruijssen 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 :) – Flater 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 – Beta Decay 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: Λ – Flater Jul 25 '18 at 13:28
• @JacobGarby: My argument was stylistic, not golfy :) – Flater 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! – Charlie 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! :-) – Charlie 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. – Kevin Cruijssen 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 – Kevin Cruijssen 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

• @BetaDecay Sorry about that. I also had the wrong byte count anyway... – Neil Jul 23 '18 at 10:45
• Nice, it gets n=0 right too – Beta Decay 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. – Jonathan Frech Jul 24 '18 at 20:45
• Though then inlining is one byte shorter. – Jonathan Frech Jul 24 '18 at 20:46
• – Jonathan Frech Jul 24 '18 at 20:50
• 321 bytes – ceilingcat 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,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. – gastropner Jul 27 '18 at 4:27
• @ceilingcat The undefined evaluation order of function arguments give me pause. – gastropner 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[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. – Kevin Cruijssen 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. :) – Kevin Cruijssen 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 :-) – Marco13 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).'^
';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. – manatwork 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. – manatwork Jul 25 '18 at 16:23
• Oh, and $i>0 and $m>0 can be written simply as $i and $m. – manatwork Jul 25 '18 at 17:33
• With trailing spaces, as in some other solutions. – manatwork 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! – manatwork 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[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. – Esolanging Fruit Jul 24 '18 at 5:26
• 307 bytes: Try it online! – Esolanging Fruit 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 – Pétur Jul 24 '18 at 11:07
• In Python 2, input() automatically eval()s the string, so you can skip the int() call as well. – Esolanging Fruit 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). – Esolanging Fruit Jul 24 '18 at 15:45