38
\$\begingroup\$

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

From the Wikipedia page on the Cool S:

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.

\$\endgroup\$
  • 10
    \$\begingroup\$ Related: Draw an S-Chain \$\endgroup\$ – Kevin Cruijssen Jul 23 '18 at 9:31
  • \$\begingroup\$ 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 :) \$\endgroup\$ – Flater Jul 25 '18 at 12:16
  • \$\begingroup\$ @Flater only problem is that /\ uses two characters, so the central vertical line would have to be offset which makes it look very untidy \$\endgroup\$ – Beta Decay Jul 25 '18 at 13:21
  • \$\begingroup\$ @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: Λ \$\endgroup\$ – Flater Jul 25 '18 at 13:28
  • 2
    \$\begingroup\$ @JacobGarby: My argument was stylistic, not golfy :) \$\endgroup\$ – Flater Jul 25 '18 at 14:14

10 Answers 10

14
\$\begingroup\$

Charcoal, 58 53 47 43 41 bytes

Nθ≔⊕⊗θδ↗θ/⊗θ↘δ^‖B↓‖M← vMδ⁰⊗θ↗⊕θM⁰δ↗θ/⊗θ⟲T

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.

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

Python 3, 255 249 248 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.

\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Kevin Cruijssen Jul 23 '18 at 11:05
  • 1
    \$\begingroup\$ Oh, and one more byte by changing p(s)\np(s[::-1]) to p(s+q+s[::-1]): 248 bytes \$\endgroup\$ – Kevin Cruijssen Jul 23 '18 at 11:13
  • \$\begingroup\$ You can save 6 bytes if you use a single print, and more 4 by removing [] from join([...]), totalizing 238 bytes \$\endgroup\$ – Rod Jul 23 '18 at 11:43
  • \$\begingroup\$ You can also store q.join in a variable to save a byte \$\endgroup\$ – Rod Jul 23 '18 at 11:48
  • \$\begingroup\$ 217. Joined all the q.joins, and a couple of other things \$\endgroup\$ – Jo King Jul 23 '18 at 12:46
13
\$\begingroup\$

Charcoal, 47 42 41 bytes

Fv^«↓⊗θ↘⊗⊕θ←↓⊗θ↙⊕⊗θ↖ι↖⊕⊗θ→↑⊗θ↗⊕θMθ⁺⊗θ⊕θ⟲⁴

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:

↖^↖⊕⊗θ→↑⊗θ↗⊕θ‖BM↓↙⊗θ→↓⊗θ⟲C↑⁴J⁰¦⁰v
\$\endgroup\$
  • \$\begingroup\$ @BetaDecay Sorry about that. I also had the wrong byte count anyway... \$\endgroup\$ – Neil Jul 23 '18 at 10:45
  • \$\begingroup\$ Nice, it gets n=0 right too \$\endgroup\$ – Beta Decay Jul 23 '18 at 10:50
6
\$\begingroup\$

Canvas, 36 32 29 bytes

«|*‼l├/L1^╋;╶╵\∔∔│α╶«├:╵╋:↔↕∔

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
\$\endgroup\$
3
\$\begingroup\$

Python 2, 227 208 207 202 196 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.

\$\endgroup\$
3
\$\begingroup\$

C (gcc), 379 353 344 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!

\$\endgroup\$
3
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ @ceilingcat Cheers. \$\endgroup\$ – gastropner Jul 27 '18 at 4:27
  • \$\begingroup\$ @ceilingcat The undefined evaluation order of function arguments give me pause. \$\endgroup\$ – gastropner Jul 27 '18 at 17:11
  • \$\begingroup\$ Suggest tucking the printf() behind the i--; \$\endgroup\$ – ceilingcat Jul 27 '18 at 17:38
2
\$\begingroup\$

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);}
}
\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Kevin Cruijssen Jul 31 '18 at 7:15
  • \$\begingroup\$ 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. :) \$\endgroup\$ – Kevin Cruijssen Jul 31 '18 at 7:33
  • \$\begingroup\$ 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 :-) \$\endgroup\$ – Marco13 Aug 1 '18 at 17:13
2
\$\begingroup\$

PHP, 378 374 378 377 376 335 331 328 bytes

-3 bytes, thanks to manatwork

-4 bytes, used str_pad instead of str_repeat

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

\$\endgroup\$
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – manatwork Jul 25 '18 at 16:02
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – manatwork Jul 25 '18 at 16:23
  • 1
    \$\begingroup\$ Oh, and $i>0 and $m>0 can be written simply as $i and $m. \$\endgroup\$ – manatwork Jul 25 '18 at 17:33
  • 1
    \$\begingroup\$ With trailing spaces, as in some other solutions. \$\endgroup\$ – manatwork Jul 25 '18 at 20:00
  • 1
    \$\begingroup\$ You can also move the declaration of $c to its first usage. Just change the . concatenation after it to ,. Try it online! \$\endgroup\$ – manatwork Jul 26 '18 at 11:37
1
\$\begingroup\$

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!

\$\endgroup\$
  • \$\begingroup\$ You can replace '\\','/' on the second line with *'\/' to save three bytes. \$\endgroup\$ – Esolanging Fruit Jul 24 '18 at 5:26
  • \$\begingroup\$ 307 bytes: Try it online! \$\endgroup\$ – Esolanging Fruit Jul 24 '18 at 5:36
  • \$\begingroup\$ 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 \$\endgroup\$ – Pétur Jul 24 '18 at 11:07
  • \$\begingroup\$ In Python 2, input() automatically eval()s the string, so you can skip the int() call as well. \$\endgroup\$ – Esolanging Fruit Jul 24 '18 at 15:42
  • \$\begingroup\$ 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). \$\endgroup\$ – Esolanging Fruit Jul 24 '18 at 15:45

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.