29
\$\begingroup\$

Background

When I was younger, I was taught a method of drawing a weird "S" shape, that I (along with my classmates) found fascinating. Today, I rediscovered it, and due to its formulaic approach to drawing it, thought it could lead to an interesting challenge :P

Drawing the "S"

The S can be drawn by following these simple steps:

First, draw 2 rows of three vertical lines like so

| | |

| | |

Next, connect the top left line with the bottom middle line and the top middle with the bottom right line to produce

| | |
 \ \
| | |

Finally, draw a top and bottom on the currently drawn image so that it ends up looking like

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

As you can see, this results in an "S" shape. When extended however (drawing it with more than 2 rows), it produces a very interesting pattern. Your task is reproduce this interesting pattern.

Task

Given an integer where n >= 2, output The S with n rows to be made from it. Output may be returned from a function, and input may be taken in standard methods. Trailing/leading whitespace for both the overall image, as well as each line, is fine. However, leading line spaces must be consistent so that the " isn't broken. You may output as a list of lines.

Test cases

input
output
---

2

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

---

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

---

10

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

This is a so shortest code wins! Good luck,

\$\endgroup\$
10
  • 15
    \$\begingroup\$ Wikipedia calls the S the Cool S, and calls an infinite version of the an S Chain \$\endgroup\$
    – Stephen
    Sep 20, 2017 at 19:16
  • \$\begingroup\$ Can we output as a list of lines? \$\endgroup\$
    – Mr. Xcoder
    Sep 20, 2017 at 19:17
  • \$\begingroup\$ @Mr.Xcoder you may \$\endgroup\$ Sep 20, 2017 at 19:17
  • \$\begingroup\$ @Stephen 10 minutes googling and this didn't come up. I'll edit the name of the question \$\endgroup\$ Sep 20, 2017 at 19:18
  • \$\begingroup\$ @cairdcoinheringaahing I searched images, that might have been it :P \$\endgroup\$
    – Stephen
    Sep 20, 2017 at 19:19

48 Answers 48

16
\$\begingroup\$

Python 2, 47 bytes

lambda k:'  ^\n / '+'\\\n| | |\n \ '*k+'/\n  v'

Try it online!

\$\endgroup\$
11
\$\begingroup\$

C# (.NET Core), 73 69 66 64 62 bytes

Two less bytes and perl-like appearance thanks to Barodus. Didn't think of using int? for nulls.

n=>$@"  ^
 / {string.Join(@"\
| | |
 \ ",new int?[++n])}/
  v"

Try it online!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ If this was a golf of the existing C# answer, I'd never have been able to tell. Well done :-) \$\endgroup\$ Sep 21, 2017 at 3:08
  • \$\begingroup\$ Can you explain what the new string[n+1] does? I have never seen it before. \$\endgroup\$
    – Ian H.
    Sep 21, 2017 at 7:39
  • \$\begingroup\$ Creates a array of empty strings AFAIK. I've used a hack with string.Join, aka join {"","","",""} with separator "\ \n | | | \n \" \$\endgroup\$ Sep 21, 2017 at 7:40
  • \$\begingroup\$ @someone Woah, I never acknowledged this trick before. Really cool! (Also my bad, i though the new string[n+1] was some kind of tricky string constructor and not an array declaration -.-) \$\endgroup\$
    – Ian H.
    Sep 21, 2017 at 8:35
7
\$\begingroup\$

Python 3, 48  56 59 61  bytes

lambda k:'  ^\n / %s/\n  v'%('\\\n| | |\n \ '*k)

Try it online!

\$\endgroup\$
6
  • \$\begingroup\$ You can save 2 bytes by unescaping the lone backslashes. \$\endgroup\$
    – L3viathan
    Sep 20, 2017 at 19:27
  • \$\begingroup\$ @L3viathan Just updating too \$\endgroup\$
    – Mr. Xcoder
    Sep 20, 2017 at 19:27
  • \$\begingroup\$ 56 bytes; not sure if this is fair game; doesn't work on TIO \$\endgroup\$
    – L3viathan
    Sep 20, 2017 at 19:36
  • \$\begingroup\$ @L3viathan That is not correct. Extra \ \. \$\endgroup\$
    – Mr. Xcoder
    Sep 20, 2017 at 19:36
  • \$\begingroup\$ On TIO: yes. In my terminal: no. \$\endgroup\$
    – L3viathan
    Sep 20, 2017 at 19:37
7
\$\begingroup\$

05AB1E, 27 26 bytes

…^
/ð"\
| | |
\ "I×…/
vJ.c

Try it online!

Alternate 27 byte version

'^…/ \©IF…| |û…\ \}\®R'v».c

Try it online!

Explanation

'^                             # push "^"
  …/ \©                        # push "/ \" and store a copy in register
       IF                      # input times do:
         …| |û                 # push "| | |"
              …\ \             # push "\ \"
                  }            # end loop
                   \           # discard top of stack (the extra "\ \")
                    ®R         # push "/ \" reversed = "\ /"
                      'v       # push "v"
                        »      # join stack on newlines
                         .c    # center each row
\$\endgroup\$
2
  • 5
    \$\begingroup\$ Your code looks a bit like an elephant to me :) \$\endgroup\$
    – Wojowu
    Sep 21, 2017 at 10:58
  • \$\begingroup\$ It's literally SCARY how close my answer was to yours: '^…/ \©IF„| ûû„\ û}\®R'v).C without looking. \$\endgroup\$ Sep 21, 2017 at 15:48
7
\$\begingroup\$

Japt, 34 25 23 bytes

" ^ /{ç'\²i|³1}/ v"¬¸ò5

Test it online! Outputs as an array of lines; -R flag added to join on newlines. (Thanks @Shaggy)

First Second attempt, might be improvable...

How it works

" ^ /{ ç'\²  i |³  1}/ v"¬ ¸  ò5
" ^ /{Uç'\p2 i'|p3 1}/ v"q qS ò5   Ungolfed
                                   Implicit: U = input number
        '\p2                       Repeat a backslash twice, giving "\\".
             i     1               Insert at index 1
              '|p3                   3 vertical bars. This gives "\|||\".
      Uç                           Make U copies of this string. U = 2: "\|||\\|||\"
" ^ /{              }/ v"          Insert this into this string.    " ^ /\|||\\|||\/ v"
                         q qS      Split into chars; join on spaces."  ^   / \ | | | \ \ | | | \ /   v"
                              ò5   Split into rows of length 5.    ["  ^  "," / \ ","| | |"," \ \ ","| | |"," \ / ","  v"]
                                   Joining on newlines gives "  ^  
                                                               / \ 
                                                              | | |
                                                               \ \
                                                              | | |
                                                               \ /
                                                                v"
\$\endgroup\$
4
  • \$\begingroup\$ Beating Charcoal and tying SOGL? Excellent work! \$\endgroup\$
    – Shaggy
    Sep 21, 2017 at 9:30
  • \$\begingroup\$ You can output an array of lines, by the way, so you can ditch the last 2 characters. \$\endgroup\$
    – Shaggy
    Sep 21, 2017 at 10:46
  • \$\begingroup\$ @Shaggy That's great, now we're winning! \$\endgroup\$ Sep 21, 2017 at 17:24
  • \$\begingroup\$ We've been doing well lately :) \$\endgroup\$
    – Shaggy
    Sep 22, 2017 at 10:40
7
\$\begingroup\$

SOGL V0.12, 26 25 18 bytes

°I-‘*"∑ūCƨΩ)¹‘@∑5n

Try it Here!

Uses the same strategy as ETHproductions's Japt answer

Explanation:

..‘           push "\|||\"
   *          repeat input times
    "..‘      push " ^ /ŗ/ v ", with ŗ replaced with POP. The reason why there's a trailing
              space is because otherwise it didn't have enough repeating characters to compress
        @∑    join with spaces
          5n  split to line lengths of 5
\$\endgroup\$
2
  • 2
    \$\begingroup\$ push "|" and " " what the heck is that builtin \$\endgroup\$
    – Steven H.
    Sep 20, 2017 at 19:35
  • 1
    \$\begingroup\$ @StevenHewitt those are actually two built-ins, but I joined them together (as I do with other stuff) because I don't think it's not necessary to separate stuff that gets used together soon \$\endgroup\$
    – dzaima
    Sep 20, 2017 at 19:37
6
\$\begingroup\$

JavaScript (ES6), 60 bytes

n=>`  ^
 / \\
${`| | |
 \\ \\
`.repeat(n-1)}| | |
 \\ /
  v`

Test Snippet

let f=
n=>`  ^
 / \\
${`| | |
 \\ \\
`.repeat(n-1)}| | |
 \\ /
  v`
;(I.oninput=_=>O.innerHTML=I.value+"\n"+f(+I.value))()
<input id=I type=range min=2 max=15 value=2><pre id=O></pre>

\$\endgroup\$
2
  • 1
    \$\begingroup\$ 57: n=>' ^\n /${' \\ \\\n| | |\n'.repeat(n).slice(2)} \\ /\n v' (using backticks and literal newlines) \$\endgroup\$
    – edc65
    Sep 21, 2017 at 9:15
  • \$\begingroup\$ Beat me by 1 bytes :( \$\endgroup\$
    – user100690
    Mar 17, 2021 at 7:48
6
\$\begingroup\$

Charcoal, 27 26 25 bytes

-1 byte thanks to Carlos Alejo. -1 byte thanks to ASCII-only.

  ^⸿ / ×\⸿| | |⸿ \ N/⸿  v

Try it online! Link is to verbose version. #charcoal-verbose-obfucation

\$\endgroup\$
4
  • 1
    \$\begingroup\$ You can save 1 byte by just calling Print (instead of adding the strings) and using \r: ` ^⸿ / ×\⸿| | |⸿ \ Iθ/⸿ v`. Verbose version. \$\endgroup\$
    – Charlie
    Sep 21, 2017 at 7:09
  • \$\begingroup\$ Ah... I'll have to remember \r as the way to get newlines the sane way. Thanks! \$\endgroup\$ Sep 21, 2017 at 15:43
  • \$\begingroup\$ 25 bytes \$\endgroup\$
    – ASCII-only
    Oct 4, 2017 at 11:25
  • \$\begingroup\$ @ASCII-only :P - \$\endgroup\$ Oct 4, 2017 at 12:54
5
\$\begingroup\$

C (gcc), 82 bytes

f(n){for(puts("  ^\n / \\");--n;puts("| | |\n \\ \\"));puts("| | |\n \\ /\n  v");}

Try it online!

\$\endgroup\$
5
\$\begingroup\$

Perl 5, 39 37 bytes

say"  ^
 / ".'\
| | |
 \ 'x<>."/
  v"

Try it online!

Shaved two bytes with @DomHastings' suggestion

\$\endgroup\$
1
  • \$\begingroup\$ If you use single quotes, you don't need to escape the backslashes for -2! :) \$\endgroup\$ Oct 27, 2017 at 12:41
3
\$\begingroup\$

Actually, 49 bytes

"| | |"@α;lD" \ \"@α@Z♂ii"  v"" \ /"))" / \""  ^"

Try it online!

Explanation:

"| | |"@α;lD" \ \"@α@Z♂ii"  v"" \ /"))" / \""  ^"
"| | |"@α                                          push a list containing n copies of the vertical lines
         ;lD" \ \"@α                               push a list containing n-1 copies of the diagonal connections
                    @Z♂i                           interleave
                        i                          flatten
                         "  v"" \ /"))             make the bottom
                                      " / \""  ^"  make the top
\$\endgroup\$
3
\$\begingroup\$

05AB1E, 38 bytes

…| |ûU"  ^
 / \"XI<F„ \2×X}" \ /
  v"»

Try it online!

…| |                         # Push "| |"
    û                        # Palindromize
     U                       # Store in X
      "..."X                 # Push the top three rows
            I<F      }       # One less than input times do:
               „ \           #   Push " \"
                  2×         #   Concatenate that with itself
                    X        #   Push "| | |"
                      "..."  # Push the last two rows
                           » # Join stack with newlines
\$\endgroup\$
3
\$\begingroup\$

C# (.NET Core), 101 77 73 bytes

Saved 24 bytes thanks to i cri everytim!
Saved 4 bytes thanks to Kevin Cruijssen!

n=>{var s="  ^\n / ";for(;n-->0;s+="\\\n| | |\n \\ ");return s+"/\n  v";}

Try it online!

As per usual, string repeating in C# is a pain.

\$\endgroup\$
4
  • \$\begingroup\$ 77 bytes. \$\endgroup\$ Sep 20, 2017 at 21:54
  • \$\begingroup\$ @icrieverytim Ahhh, of course, thats way better. \$\endgroup\$
    – Ian H.
    Sep 21, 2017 at 7:39
  • \$\begingroup\$ You can change --n>=0 to n-->0 and s+="/\n v";return s; to return s+"/\n v"; to save some bytes. \$\endgroup\$ Sep 21, 2017 at 7:54
  • 1
    \$\begingroup\$ @KevinCruijssen Thanks, fixed! \$\endgroup\$
    – Ian H.
    Sep 21, 2017 at 9:15
3
\$\begingroup\$

Retina, 38 bytes

.+
$*
1
¶|||¶x\\
^
 ^¶x/\
.$
/¶ v
x?
 

Try it online!

Prints a column of leading spaces and on trailing space on each line.

Explanation

The main byte savings come from omitting the spaces in all the literal parts and inserting them at the end. The figure is structured such that there are never two non-spaces next to each other, so if we just remove them all, we can almost fix the shape by inserting a space at every position at the end:

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

becomes:

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

That's almost correct, except for indentation. The ^ and v are missing two spaces. That's actually easier to fix, because if we just insert an explicit space in front of each of them, that'll result in two additional spaces at the end. The lines with the slashes are trickier because they require just one additional space. To fix this, we insert a placeholder character there (x). When we insert the spaces at the end, we don't just insert them for every empty match, but we optionally match that x. That means instead of inserting a space in front of the x, the x itself gets replaced. And then there will still be an empty match right after the x. That means, every x adds exactly one space without changing anything else. So what we want to set up is this:

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

which will give us the desired result. So here's the code:

.+
$*

Convert the input to unary.

1
¶|||¶x\\

Convert each 1 to two lines with ||| and x\\ (and a leading linefeed).

^
 ^¶x/\

Inser the first two lines with ^ and x/\.

.$
/¶ v

Fix the final x\\ by turning the last \ into / and appending a line with the v.

x?
 

Replace each x or empty match with a space.

\$\endgroup\$
1
  • \$\begingroup\$ Neat approach. I was trying to figure out a way to use join-on-spaces for my Pip solution, but it didn't quite work due to the different numbers of leading spaces on different rows. \$\endgroup\$
    – DLosc
    Sep 21, 2017 at 16:21
3
\$\begingroup\$

Stax, 21 20 bytes

⌐èüYΩ╜yu╝√♪╪▌yº⌐▌2Σ⌠

Run and debug it

Uses ETHProductions' idea.

-1 after changing 1/ to M (from recursive).

\$\endgroup\$
2
\$\begingroup\$

Pyth, 46 bytes

"  ^
 / \\"
+*j[jd*\|3" \ \\"k))Q" \ /
  v

Test suite.

\$\endgroup\$
2
  • \$\begingroup\$ 36 bytes: %" ^\n / %s/\n v"*Q"\\\n| | |\n \ \$\endgroup\$
    – Mr. Xcoder
    Sep 20, 2017 at 20:05
  • \$\begingroup\$ 31 bytes. \$\endgroup\$
    – Mr. Xcoder
    Sep 20, 2017 at 20:11
2
\$\begingroup\$

Pyth, 40 bytes

K" / \ ""  ^"Kj+b+*2+d\\b*Q]*3"| "_K"  v

Fairly similar to Steven Hewitt's, but developed independently.

Try it Online

Explanation

K" / \ ""  ^"Kj+b+*2+d\\b*Q]*3"| "_K"  v
K" / \ ""                                 Set K = " / \ "
        "  ^"                       "  v  Draw the end points.
             K                    _K      Draw the slants.
                         *Q]*3"| "        Draw the vertical bars...
              j+b+*2+d\\b                 ... interspersed with slants.
\$\endgroup\$
2
\$\begingroup\$

Pyth, 33 32 31 bytes

Thanks Mr. Xcoder for one byte.

%"  ^
 / %s/
  v"*tj\|_B" \\
| 

Try it online: Demonstration or Test Suite

\$\endgroup\$
2
  • \$\begingroup\$ Very nice answer! You can bring it down to 32 bytes. \$\endgroup\$
    – Mr. Xcoder
    Sep 20, 2017 at 20:07
  • 2
    \$\begingroup\$ 31 bytes, in fact. \$\endgroup\$
    – Mr. Xcoder
    Sep 20, 2017 at 20:07
2
\$\begingroup\$

Retina, 45 bytes

This is a pretty simple solution.

.+
$*
^1
  ^¶ /x
$
 \ /¶  v
1
 \x
x
 \¶| | |¶

Try it online

If the art could be 1-indexed instead, it'd be a bit shorter (44 bytes):

.+
  ^¶ /x$0$*1
$
 \ /¶  v
1
 \x
x
 \¶| | |¶
\$\endgroup\$
2
\$\begingroup\$

Pip, 45 42 33 bytes

"  ^
 / "."\
| | |
 \ "Xa."/
  v"

Try it online!

Explanation

The code is really simple, though the newlines make it harder to read. Here's a better way to see the structure:

"prefix" . "repeated" X a . "suffix"

The repeated element in the S-chain is

   \
| | |
 \

Take this as a literal string and repeat it a times (where a is the first command-line argument). Then prepend the prefix:

  ^
 /

and append the suffix:

   /
  v

and print.

(I like how this ended up looking kinda like a ><> program.)

\$\endgroup\$
1
  • \$\begingroup\$ This looks like Lumpy Space Princess from Adventure Time :) \$\endgroup\$
    – YSC
    Sep 21, 2017 at 15:30
2
\$\begingroup\$

AsciiDots, 88 bytes

.*$"  ^"$" / \"
/>#?)--*$"| | |"$" \ \"
*#1\ /-~$"| | |"$" \ /"$"  v"
*-{-}*[<]
\#0----/

Try it online!

\$\endgroup\$
2
\$\begingroup\$

MATL, 47 44 43 bytes

-3 bytes thanks to Giuseppe

'  ^' ' / \ 'XK'| | |'XJGq:"' \'thJ]KP'  v'

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ ' ^' ' / \ 'XK'| | |'XJ`' \ \'JGq@-]KP' v' is 44 bytes. \$\endgroup\$
    – Giuseppe
    Sep 21, 2017 at 17:53
2
\$\begingroup\$

bash, 67 bytes

printf -v a %\*s $1 \ ;echo '  ^
 / '"${a// /\\
| | |
 \\ }"'/
  v'

Try it online

\$\endgroup\$
2
\$\begingroup\$

Ruby, 39 bytes

->n{"  ^
 / #{"\\
| | |
 \\ "*n}/
  v"}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

///, 54 bytes

/*/
| | |
b//b>///b/ \\\\ \\\\/  ^
 \/ \\**> \\ \/
  v

Try it online!

For input, change the number of asterisks

 \/ \\**> \\ \/ 
      ^^
\$\endgroup\$
2
  • \$\begingroup\$ How does this take input? Changing the "Input" field on TIO does nothing \$\endgroup\$ Mar 23, 2021 at 17:06
  • \$\begingroup\$ I forgot about that, it takes input in unary. You change the number of asterisks in the middle, the one in the example is 2.(technically I could delete them to save 2 bytes but i dont care) \$\endgroup\$ Mar 24, 2021 at 17:15
1
\$\begingroup\$

Haskell, 53 bytes

f n="  ^\n /"++([1..n]>>" \\\n| | |\n \\")++" /\n  v"

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Java 8, 93 76 bytes

n->{String r="  ^\n / ";for(;n-->0;r+="\\\n| | |\n \\ ");return r+"/\n  v";}

Port of @IanH.'s C# .NET answer after I golfed it a bit more.

Try it here.

\$\endgroup\$
2
  • \$\begingroup\$ It's funny how this is almost exactly identical expect for the string vs var part. \$\endgroup\$
    – Ian H.
    Sep 21, 2017 at 8:34
  • \$\begingroup\$ @IanH. And the n-> vs n=> ;) \$\endgroup\$ Sep 21, 2017 at 9:11
1
\$\begingroup\$

Excel, 60 bytes

="  ^
 / \
"&REPT("| | |
 \ \
",A1-1)&"| | |
 \ /
  v"
\$\endgroup\$
1
  • \$\begingroup\$ You should consider checking to see if this is a polyglot with Google Sheets \$\endgroup\$ Oct 4, 2017 at 14:23
1
\$\begingroup\$

SpecBAS - 74 bytes

1 INPUT n
2  ?"  ^"'" / \"'("| | |"#13" \ \"#13)*(n-1);"| | |"'" \ /"'"  v"

Apostrophe moves to next line, but doesn't work inside the string being repeated, so have to use #13 to insert line feeds in that part.

\$\endgroup\$
1
\$\begingroup\$

PowerShell, 83, 57 bytes

"  ^
 / \"
1..--$args[0]|%{"| | |
 \ \"}
"| | |
 \ /
  v"

Try it online!

Per @AdmBorkBork's suggestions,

  • Simplified for by using a number range.
  • Replaced ;'s and combined strings.
  • Removed an unnecessary variable definition.
\$\endgroup\$
4
  • \$\begingroup\$ You can golf your for loop a lot by using 1..--$args[0]|%{ }. \$\endgroup\$ Sep 21, 2017 at 12:34
  • \$\begingroup\$ Also, you can use literal newlines between the adjacent strings to save on ";" and it's cheaper to get rid of $s entirely. 57 bytes \$\endgroup\$ Sep 21, 2017 at 12:40
  • \$\begingroup\$ Slick. I like the newline save. Funny that I missed the 1..$args opportunity. I'm not sure what the correct etiquette is on this site. Do I make changes to my answer and credit you, or do you post your solution as a separate answer? \$\endgroup\$
    – root
    Sep 21, 2017 at 13:09
  • \$\begingroup\$ Editing in the changes and giving credit is the proper etiquette. Welcome to PPCG. \$\endgroup\$ Sep 21, 2017 at 13:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.