73
\$\begingroup\$

As a programmer, you've probably heard of forward slashes and backward slashes. But have you heard of downslashes? That's when you take a bunch of slashes, connect their ends and draw them going down.

For today's challenge, you must write a program or function that takes a string consisting purely of slashes, and outputs all of those slashes drawn downwards in a line connecting them. This will be a lot more clear if you see an example. Given the string \\\//\/\\, you should output:

\
 \
  \
  /
 /
 \
 /
 \
  \

Here are some clarifications:

  • There must be one slash per line.

  • The first line will have 0 leading spaces.

  • For each pair of slashes:

    • If they are different from each other, they will be drawn in the same column. For example, \/ will give:

      \
      /
      
    • If they are the same character, the lower one is in the direction pointed to, that is moving to the right for a backslash, and moving to the left for a forward slash. So \\// will give

      \
       \
       /
      /
      
  • Each line may have extra trailing whitespace as long as this doesn't change the visual appearance of the output. Up to one trailing and leading newline is also acceptable. Extra leading spaces are not permitted!

In order to keep this simpler, you can assume that the string will never contain too many forward slashes. In other words, no prefix of the input will contain more forward slashes than backslashes, so an input like \\//// or // will never be given. This also means that every input will start with a backslash.

If your input is taken as a string literal, you may escape the backslashes if this is necessary. You will also never need to handle an input that is empty, or contains characters other than a slash.

You may output by any reasonable format.

As usual, this is a challenge, so try to make the shortest solution possible, even if you pick a language where this is rather difficult. Bonus points for explaining any interesting techniques you used to take bytes off!

Examples

#Input
\\\\\\\\\\\

#Output
\
 \
  \
   \
    \
     \
      \
       \
        \
         \
          \

#Input
\\\//\\/\//\\///

#Output
\
 \
  \
  /
 /
 \
  \
  /
  \
  /
 /
 \
  \
  /
 /
/


#Input
\/\/\/

#Output
\
/
\
/
\
/
\$\endgroup\$
5
  • 14
    \$\begingroup\$ The backslashes make for an annoying amount of escaping lol... \$\endgroup\$ Commented Sep 13, 2017 at 22:28
  • \$\begingroup\$ Is the formfeed/backslash method of moving the cursor around given in my answer permissible for this question? \$\endgroup\$ Commented Sep 14, 2017 at 1:15
  • \$\begingroup\$ Can we output a list of lines? \$\endgroup\$ Commented May 30, 2021 at 21:19
  • \$\begingroup\$ @cairdcoinheringaahing That seems like a reasonable IO method to me \$\endgroup\$
    – DJMcMayhem
    Commented May 31, 2021 at 0:08
  • \$\begingroup\$ @totallyhuman try python’s raw string: r"/\\////\\/\/\/\\\\//////\/" needs no escaping for any of the slashes. \$\endgroup\$ Commented May 19, 2023 at 11:45

60 Answers 60

1
2
1
\$\begingroup\$

Perl, 40 + 2 bytes

/\//&&$.--,say($"x$.,$_),/\\/&&$.++for@F

You need the -F flag.

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

V, 14 bytes

\/j>G
ç¯/<G

Try it online!

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

Perl, 34 38 + 1 bytes

to handle the two cases

s,(/)|.,$"x($1?$c&&--$c:$c++).$&.$/,ge

to be run with -p option

s,(/)|.,$"x($1?--$c:$c++).$&.$/,ge

EDIT: following comment doesn't work when first character is /

s,(/)|.,$"x($1?$c--:++$c).$&.$/,ge

however output will be shifted one character on the right if first char is \

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Doesn't work for /\\/\\/. \$\endgroup\$
    – Neil
    Commented Sep 14, 2017 at 9:59
  • \$\begingroup\$ With the updated question your original 34 solution is now perfectly valid \$\endgroup\$
    – Ton Hospel
    Commented Feb 8, 2018 at 19:35
1
\$\begingroup\$

VBA (Excel), 181 bytes

Sub q()
a = Cells(1, 1)
For x = 1 To Len(a)
c = Mid(a, x, 1)
If c = "\" Then: Debug.Print b & c: b = b + " "
If c = "/" Then: b = Left(b, Len(b) - 1): Debug.Print b & c
Next
End Sub
\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can golf this down significantly without changing your algorithm by taking advantage of the autoformatting nature of Excel VBA and by use of [...] notation: I got it down to 128 Bytes Sub q For x=1To[Len(A1)] c=Mid([A1],x,1) If c="\"Then Debug.?b;c:b=b+" " If c="/"Then b=Left(b,Len(b)-1):Debug.?b;c Next End Sub \$\endgroup\$ Commented Sep 15, 2017 at 17:50
  • \$\begingroup\$ Thank you for golfing my script. I learned something from this and will apply in the future. :) Didn't know I can use that to fetch data directly to the cells. Thanks again :) \$\endgroup\$
    – remoel
    Commented Sep 18, 2017 at 4:42
1
\$\begingroup\$

Pyth, 24 21 bytes

Port from Rod's answer.

VQ=-Z<N\<+*ZdN=+Z>N\<

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Invalid, prints [extra leading space on the first line if the string starts with \. BTW where is your code? \$\endgroup\$
    – Mr. Xcoder
    Commented Sep 14, 2017 at 12:59
  • \$\begingroup\$ @Mr.Xcoder fixed \$\endgroup\$ Commented Sep 14, 2017 at 13:05
1
\$\begingroup\$

SOGL V0.12, 16 13 bytes

{└=-:↕PFoF┘=+

Try it Here! - expects input on the stack, so for ease-of-use , is added

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

Excel VBA, 74 72 Bytes

Anonymous VBE immediate window function that takes input from cell [A1] and outputs to the VBE immediate window

For i=1To[Len(A1)]:c=Mid([A1],i,1):s=s+(c="/"):?Spc(s)c:s=s-(c="\"):Next

Example I/O

[A1]="\\\//\\/\//\\///"
For i=1To[Len(A1)]:c=Mid([A1],i,1):s=s+(c="/"):?Space(s)c:s=s-(c="\"):Next
\
 \
  \
  /
 /
 \
  \
  /
  \
  /
 /
 \
  \
  /
 /
/
\$\endgroup\$
1
\$\begingroup\$

Implicit, 25 bytes

~.(´?`/ò](0ß´);@ß1?`\ó~.ö

Try it online!

Ungolfed/explanation:

~.         read input, increment
(          do..while top of stack truthy
 ´         decrement

 ?`/{      if input equal to /
   ]´[      decrement memory
 }

 ](0       pull memory, do..while truthy
  @32       print a space
  ´         decrement
 );        pop

 @@10      print input, print a newline

 ?`\{      if input equal to \
   ].[      increment memory
 }

 ~.        read input, increment
)          loop
&          exit (avoid implicit output)

Note that ß is equal to @32, ò is equal to ]´[, ó is equal to ].[, and ö can be used in place of )& when at the end of a program.

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

Python 3, 78 bytes

a,x='',0
for i in input():x+=((1*i!='/')-(1*i=='/'))*(a==i);print(' '*x+i);a=i

Try it online!

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

brainfuck, 151 bytes

>->++++[>++++++++<-]>>+[[-]>[-]>,[<+<+>>-]<<[>++++>-[<->-----]+<[<<<<+[>+<-]>[<+>>.<-]>>>>-]>[<<<<<[>+<-]>[<+>>.<-]->>>>->]<<<.>>>++++++++++.[-]>]<<<<]

Try it online!

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

J, 28 27 22 bytes

({."0~+/\-0&<)_1^'\'=]

Try it online!

Thanks to Bubbler for catching a bug and for -6 bytes!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ I think first column is truncated? Fixing it and using _1^ gives 27 bytes. \$\endgroup\$
    – Bubbler
    Commented Sep 7, 2020 at 6:41
  • \$\begingroup\$ Thanks. The _1 trick is more elegant anyway. \$\endgroup\$
    – Jonah
    Commented Sep 7, 2020 at 6:44
  • \$\begingroup\$ I got it down to 22 bytes. \$\endgroup\$
    – Bubbler
    Commented Sep 7, 2020 at 6:57
  • \$\begingroup\$ There is golfed... and then there is Bubbler-ed! \$\endgroup\$
    – Jonah
    Commented Sep 7, 2020 at 7:08
1
\$\begingroup\$

C (gcc), 96 71 70 bytes

Awesome -25 solution by ceilingcat

And another -1 by ceilingcat. ASCII bit hacks ftw

c;p;main(i){for(;read(0,&c,1);printf("%*c\n",i,p=c))c-p?:c&1?--i:++i;}

Try it online!

Ungolfed

c; /* character */
p; /* previous character */

main(i /* indent */)
{
    for (; read(0, &c, 1); printf("%*c\n", i, p = c))
        c - p ? : c & 1 ? --i : ++i;
}

Explanation

read takes 1 byte from the file descriptor 0 (stdin) and stores it in c.

c - p checks if c and p are different. c & 1 checks if c is a forward slash. So the entire conditional increments the indent if the character and the previous character are both backslashes, and decrements the indent if they're both forward slashes.

Then we print c with i leading spaces. We also assign p = c for the next iteration.

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

PowerShell, 47 bytes

switch($args){'\'{' '*$i+++$_}'/'{' '*--$i+$_}}

Try it online!

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

PowerShell, 71 69 bytes

-2 bytes thanks to mazzy

$z=92
$args|%{$i+=($x=2*($_-eq92)-1)*($z-ne$_)
' '*$i+($z=$_)
$i+=$x}

Try it online!

Takes input by splatting. This also saves us two bytes because we can just treat it as an int instead of writing '\' which we do twice.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ nice. ($x=2*($_-eq92)-1) ? \$\endgroup\$
    – mazzy
    Commented Sep 9, 2020 at 6:51
1
\$\begingroup\$

Excel, 125 bytes

=LET(q,SEQUENCE(LEN(A1)),x,MID(A1,q,1),REPT(" ",MMULT(IF(TRANSPOSE(q)>q,,1),IF(q=1,,(INDEX(x,q-1)="\")-(INDEX(x,q)="/"))))&x)

Link to Spreadsheet

This is a port of Taylor Scott's VBA answer.

Explanation

  • =LET(q,SEQUENCE(LEN(A1)), q = vertical array [1..LEN(A1)]
  • x,MID(A1,q,1), x = The characters in A1 in a vertical array
  • IF(q=1,,(INDEX(x,q-1)="\")-(INDEX(x,q)="/")) the change in the number of spaces from the prior line; +1 if the prior line was "", -1 if the current line is "/"
  • IF(TRANSPOSE(q)>q,,1) a lower triangular matrix of 1s
  • MMULT(~,~) matrix multiply the change array and the lower triangular matrix to get the number of spaces for each line
  • REPT(" ",~)&x) for each line output the number of spaces & characters
\$\endgroup\$
1
\$\begingroup\$

Pyth, 20 bytes

jm?qd\\+*;~hZd+*;=tZ

Test suite

The other two existing Pyth answers use different approaches (and an older version of the language).

Explanation:
jm?qd\\+*;~hZd+*;=tZ   | Full program
jm?qd\\+*;~hZd+*;=tZdQ | with implicit variables added
-----------------------+------------------------------------------------
 m                   Q | For each character d in the input:,
  ?qd\\                |  if d is '\',
        *;             |   create a string of n spaces, where n is
          ~hZ          |    Z, but then store Z + 1 in Z (Z begins as 0)
       +     d         |   add d to the end of the string
  ?                    |  otherwise,
              +*;   d  |   do the same, but with (below) spaces
                 =tZ   |    Z - 1, stored in Z
j                      | Join the results by newline.
\$\endgroup\$
2
  • \$\begingroup\$ The test suite's input is missing a trailing ". \$\endgroup\$ Commented May 30, 2021 at 22:37
  • \$\begingroup\$ @JonathanAllan thanks for the heads up \$\endgroup\$
    – hakr14
    Commented May 31, 2021 at 0:03
1
\$\begingroup\$

Vyxal, 8 bytes

Cæ:d⌐¦+↳

Try it Online! Outputs as a list of lines, formatting in footer

C        # Charcodes: "/" -> 47, "\" -> 92
 æ       # Are prime? "/" -> 1, "\" -> 0
   d⌐    # Double and take one's complement "/" -> -1, "\" -> 1
     ¦   # Cumulative sums
      +  # Add...
 æ:      # Is prime? (indents "/" by one extra space)
       ↳ # Pad to these lengths
\$\endgroup\$
1
  • 1
    \$\begingroup\$ are you literally trying to make this slow? is much faster than a primality test :p \$\endgroup\$
    – naffetS
    Commented Nov 23, 2022 at 0:27
1
\$\begingroup\$

Julia 1.0, 67 bytes

s->(x=[s...];@.println(lpad(x,$cumsum(1-2(x<'0')-[0;$diff(x)]%2))))

Try it online!

  • -3 bytes thanks to @MarcMush: replace isodd(_) with (_.%2)
  • -6 bytes thanks to @MarcMush: use @. to vectorize multiple expressions
  • -3 bytes thanks to @amelies: replace string repeats with lpad
  • -1 byte thanks to @MarcMush: replace 'x=='/' with x<'0'
\$\endgroup\$
4
  • 1
    \$\begingroup\$ I think you can use .%2 instead of isodd \$\endgroup\$
    – MarcMush
    Commented Nov 19, 2022 at 20:46
  • 1
    \$\begingroup\$ Also maybe a @. instead of all the broadcasting \$\endgroup\$
    – MarcMush
    Commented Nov 19, 2022 at 20:47
  • 1
    \$\begingroup\$ 72 bytes using lpad and removing one *: s->(x=[s...];@.println(lpad(x,$cumsum(1-2(Int(x)%2)-[0;$diff(x)]÷45)))) \$\endgroup\$
    – amelies
    Commented Nov 22, 2022 at 13:12
  • 1
    \$\begingroup\$ You can use x<'0' instead of x=='/' \$\endgroup\$
    – MarcMush
    Commented Nov 22, 2022 at 21:11
1
\$\begingroup\$

Rockstar, 110 92 90 bytes

listen to S
cut S
Y's -1
while S
roll S in C
let Y be+C's "\"
say " "*Y+C
let Y be-C's "/"

Try it here (Code will need to be pasted in)

listen to S     :Read input string into variable S
cut S           :Split into an array
Y's -1          :Initialise Y as -1
while S         :While S is not empty
roll S in C     :  Pop the first element into variable C
let Y be+       :  Increment Y by
  C's "\"       :    C is equal to "\"
say " "*Y+C     :  Output Y spaces & C
let Y be-       :  Decrement Y by
  C's "/"       :    C is equal to "/"
\$\endgroup\$
1
\$\begingroup\$

Thunno 2, 11 bytes

JCPDḌ€ḷṡ+ðṙ

Attempt This Online!

Explanation

JCPDḌ€ḷṡ+ðṙ  # Implicit input
JC           # Charcodes of input
  PD         # Are prime, duplicate
    Ḍ€ḷ      # Double, complement
       ṡ+    # Add to cumsums
         ðṙ  # Right-justify
             # Implicit output
\$\endgroup\$
0
\$\begingroup\$

Python 2, 86 76 75 bytes

-1 byte thanks to Neil.

p,i='',0
for c in input():i+={'\\\\':1,'//':-1}.get(p+c,0);print' '*i+c;p=c

Try it online!

Fairly lame approach, I will try to golf the mapping at least. NVM I got rekt by another answer. >_>

\$\endgroup\$
0
0
\$\begingroup\$

Rust, 165 bytes

fn f(s:&str){let(_,a)=s.chars().fold((0,"".to_string()),|(i,r),c|(if c<'<'{i-1}else{i+1},format!("{}{}{}\n",r," ".repeat(if c<'<'{i-1}else{i}),c)));println!("{}",a)}

Try it online!

It's an adaptation of Rod's answer in Python 2.

\$\endgroup\$
0
\$\begingroup\$

c64 basic v2, 71 70 61 bytes

1rEs:x=1024:fOy=1tolE(s):a=aS(mI(s,y,1)):pOx,a:x=x-165+a*2:nE

Input can be given as

0dA"\\/\/\\/\//"

If the string is longer as 25, the program will overwrite its own memory. And we won't do that, because basic programs overwriting themselves with POKEs contradict the OO paradigm.

\$\endgroup\$
0
\$\begingroup\$

GolfScript - 117 bytes

1/{'/'=}%1:s;[{s}{..(\;!?.0<{;,0:s;}{.@\>}if}while]0:M;1:i;{,{i*}%:a{M+' '*i 0<{'/'}{"\\"}if +"\n"+}/a)M+:M;;i~):i;}/

Ungolfed version

1/{'/'=}%
1:s;
[{s}
{
  ..(\;!?.0<{;,0:s;}{.@\>}if
}
while]
0:M;
1:i;
{
  ,{i*}%:a{M+' '*i 0<{'/'}{"\\"}if +"\n"+}/
  a)M+:M;;
  i~):i;
}/

At first glance it looked easy... it took me 2.5 hours. Probably there is room for improvement, perhaps tomorrow I'll do some optimization.

\$\endgroup\$
0
\$\begingroup\$

SmileBASIC, 65 bytes

INPUT S$WHILE""<S$C$=SHIFT(S$)DEC N,@L>C$?" "*N;C$INC N,@H<C$WEND
\$\endgroup\$
0
\$\begingroup\$

JavaScript, 49 48 bytes

Takes input as an array of individual characters and outputs an array of lines.

a=>a.map(c=>" ".repeat(x+=d=c>'/',x-=!d)+c,x=-1)

Saved a byte borrowing a trick from the other JS solution.


Try it

f=
a=>a.map(c=>" ".repeat(x+=d=c>'/',x-=!d)+c,x=-1)
o.innerText=[String.raw`\\\\\\\\\\\\`,String.raw`\\\//\\/\//\\///`,String.raw`\/\/\/`].map(s=>f([...s]).join`\n`).join`\n\n`
oninput=_=>o.innerText=f([...i.value]).join`\n`
<input id=i><pre id=o>

\$\endgroup\$
0
\$\begingroup\$

K4, 31 bytes

Solution:

-1(-1+\a-a*~~':a:-1 1"/"=x)$$x:

Examples:

q)k)-1(-1+\a-a*~~':a:-1 1"/"=x)$$x:"\\\\\\//\\\\/\\//\\\\///"
\
 \
  \
  /
 /
 \
  \
  /
  \
  /
 /
 \
  \
  /
 /
/

Works if you start with a / too:

q)k)-1(-1+\a-a*~~':a:-1 1"/"=x)$$x:"/\\\\/\\\\/"
/
\
 \
 /
 \
  \
  /

Explanation:

Generate list of negative numbers to (left) pad each of the input characters. Struggled to get a formula that worked, will look at the other solutions to see if there is a more simple method:

q)k)"/"=x
0001100101100111b
q)k)-1 1"/"=x
-1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 1 1 1
q)k)~~':a:-1 1"/"=x
1001010111010100b
q)k)a*~~':a:-1 1"/"=x
-1 0 0 1 0 -1 0 1 -1 1 0 -1 0 1 0 0
q)k)a-a*~~':a:-1 1"/"=x
0 -1 -1 0 1 0 -1 0 0 0 1 0 -1 0 1 1
q)k)+\a-a*~~':a:-1 1"/"=x
0 -1 -2 -2 -1 -1 -2 -2 -2 -2 -1 -1 -2 -2 -1 0
q)k)-1+\a-a*~~':a:-1 1"/"=x
-1 -2 -3 -3 -2 -2 -3 -3 -3 -3 -2 -2 -3 -3 -2 -1

Full breakdown:

-1(-1+\a-a*~~':a:-1 1"/"=x)$$x: / the solution
                             x: / save input as variable x
                            $   / string (converts to char lists))
                           $    / pad
  (                       )     / do this together
                     "/"=x      / boolean list of x equal to /
                 -1 1           / index into this list
               a:               / save as variable a
           ~~':                 / differ (not-not-each-previous)
         a*                     / multiply by a
       a-                       / subtract from a
     +\                         / sums
   -1                           / (start summing from -1)
-1                              / print to stdout
\$\endgroup\$
0
\$\begingroup\$

Japt -R, 13 bytes

¬®ùZ>'/?°V:V´

Try it online!

Unpacked & How it works

Uq mZ{ZùZ>'/?++V:V--

Input: U = string of / and \, V = 0 (default)

Uq                    Split into chars
   mZ{                Map...
        Z>'/?           If the char is rightward (backslash)...
             ++V          Pre-increment V
                :V--      Otherwise, post-decrement V
      Zù                Left-pad the char with spaces to length V

-R                    Join with newline before printing
\$\endgroup\$
0
\$\begingroup\$

Pip, 28 bytes

FlaIlQ'\PsX++v.lE{PsXv.l--v}

With a post decrement operator, this could be way shorter.

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Ruby, 47 42 bytes

-5 bytes thanks to Steffan

Inspired by pxeger's Zsh answer.

->a{w=0
a.map{" "*(_1<?@?w-=1:~-w+=1)+_1}}

Attempt This Online!

\$\endgroup\$
1
  • \$\begingroup\$ 42 \$\endgroup\$
    – naffetS
    Commented Nov 23, 2022 at 0:31
1
2

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.