The Great Pyramid of ASCII

Introduction

It's 2600 BC and people are building pyramids now. They already made the basis of the pyramid but don't know how to continue. So, they called you for help.

The rules of making a pyramid is quite simple. For the layer above the previous layer, all you need to do is follow this step-by-step hand guide:

1. Cut the edges off the previous layer.

2. Above the / character, there must be a \ character and vice versa. This applies to every character except the edges.

3. The leftmost character is always a / and the rightmost character is always \.

Let's take an example of a basis for a pyramid:

//\/\/\\

We cut off the edges, leaving:

/\/\/\

We change the forward slashes with backward slashes and vice versa:

\/\/\/

The leftmost character is always a / and the rightmost character is always a \, so we change that:

//\/\\

We place this layer on the previous layer:

//\/\\
//\/\/\\

We continue until the top is reached (which looks like /\). So, eventually we get:

/\
//\\
//\/\\
//\/\/\\

This is what you need to output.

Given the basis of a pyramid (with a length greater than 3), output the full pyramid. You can safely assume that the leftmost character is / and the rightmost character is a \. You can also assume that the length of the basis is always even. The use of trailing spaces is allowed. The use of leading spaces is also allowed, as long as the pyramid stays in place. The use of 1 trailing and 1 leading newlines is allowed.

Test cases

Input: /\\\
Output:
/\
/\\\

Input: //\\///\/\
Output:
/\
/\\\
/\///\
///\\\/\
//\\///\/\

Input: /////////////\
Output:
/\
/\\\
/////\
/\\\\\\\
/////////\
/\\\\\\\\\\\
/////////////\

This is , so the submission with the least amount of bytes wins!

Jelly, 28 26 25 24 bytes

QṚ,QyḊḊṖṖj@QµÐĿµJ’⁶ẋ⁸żYṚ

-4 bytes thanks to Dennis

Recipe:

QṚ,QyḊḊṖṖj@QµÐĿµJ’⁶ẋ⁸żYṚ - one argument: input()
Q  Q       Q             - set of Left=input(): "/\"
Ṛ                       - reverse Left: "\/"
,                      - Left-pair-Right: ["\/","/\"]
ḊḊṖṖ                - dequeue Left twice, then pop twice: input()[2:-2]
y                    - translate Right with mapping in Left: swaps internal slashes
j@              - join Right with separator Left (@ swaps operands)
µ  µ         - chain separators to form a 1,1,1 chain of chains
ÐĿ          - loop while results are unique and collect them
J        - yield [1,...,len(Left=input())]
’       - decrement: [0,....len(input())-1]
⁶      - " "
ẋ     - repeat Left Right times: ["", " ", ...]
⁸ż   - zip Right and Left (⁸ is the link's Left argument):
...pads the loop results
Y  - joins Left with line-feeds
Ṛ - reverse Left

(serve with lemonade, those pyramids make for thirsty workers)

Cook up your own slash pyramid at TryItOnline, or try out all the OP's suggested tasters

Retina, 595654 52 bytes

{^( *)/.(.*)..
$1 /$2\¶$0 T/\\Ro(?<=^ +/).+(?=.) Try it online! Sample output /\ /\\\ /\///\ ///\\\/\ //\\///\/\ • – Martin Ender Aug 23 '16 at 14:34 Pyth - 27 26 bytes Reduces by the operation given in the OP until it repeats, which is the case for the blank line. j_.e+*kdb.ujXtPtPNK"\/")_K Python 2, 78 bytes f=lambda s,p='\n':(s[2:]and f('/%s\\'%s.translate('/\\'*128)[2:-2],p+' '))+p+s A recursive function that outputs a string. Each layer of the pyramid is appended to the recursive call with the layer above it. The prefix p, which starts as a newline character gains one more space to make the triangle. The next layer is produced by swapping slashes, cutting off the first and last two symbols, and sandwiching it inside a left and right slash. Python 3 can save a byte by doing *99 in the translate, as the length-256 requirement was dropped. • Clever using translate, but do we not have to print? – Jonathan Allan Aug 20 '16 at 20:40 • @JonathanAllan Not by default, you just have to output as the challenge says. – xnor Aug 20 '16 at 20:42 Haskell, 989490 85 bytes q=init.tail s '/'='\\' s _='/' t#""=t++"\\\n" t#l=(' ':t)#(s<$>q l)++t++l#""
("/"#).q

Usage example (note: in Haskell backslashes within literal strings have to be escaped \\):

*Main> putStr $(("/"#).q) "//\\\\///\\/\\" /\ /\\\ /\///\ ///\\\/\ //\\///\/\ Simple recurse approach: # does the work by mapping s, which flips the / and \, on the inner elements. The additional parameter t keeps track of the indention level and is expanded by a space on each recursive call. Note: the second recursive call of # (-> l#"") jumps directly to the base case and is just a short way to add l, \ and a newline, i.e. it replaces ++l++"\\\n". Edit: @xnor saved 5 bytes. Thanks! • l++"\\\n" looks like l#"". – xnor Aug 20 '16 at 20:45 • An interesting way to swap two characters in a string s is [c|x<-s,c<-"ab",c/=x]. – xnor Aug 20 '16 at 20:53 • @xnor: I've tried many things to get rid of the second ++"\\\n", but missed this one. Thanks! – nimi Aug 20 '16 at 21:05 Python 3, 108 104 101 94 91 89 88 bytes b,f='\/';p=lambda t,n='\n':(t[2:]and p(f+''.join(map({f:b,b:f}.get,t[2:-2]))+b,n+' '))+n+t -7 bytes thanks to xnor (letting me know we don't have to print!) -3 bytes thanks to xnor (taking declaration outside of function declaration [d'oh]) -1 byte thanks to Dennis (replace f,b='/\\' with b,f='\/') Test it on ideone. Note: input adjusted for double backslash (even raw strings won't work if they end in an odd number of backslashes). • You can jointly declare f,b='/\\' outside the function. – xnor Aug 20 '16 at 21:00 • @xnor Thanks, I can't count ^^ – Jonathan Allan Aug 20 '16 at 21:11 JavaScript (ES6), 91 86 bytes f= (s,t= )=>s?f(/${s.slice(2,-2).replace(/./g,c=>c>/?/:\\)}\\,t+ )+t+s:t+s
;
<input placeholder=Basis oninput=o.textContent=f(this.value)><pre id=o>

Output includes a leading newline character.

Ruby, 80 bytes

f=->s{s[-3]>?!&&f[" "+s.gsub(/^( *\/).|.(.$)?/){$1||$2||($&>?/??/:?\\)}]
puts s}

Ungolfed

f = ->s{
s[-3] > ?! &&
f[" " + s.gsub(/^( *\/).|.(.$)?/) {$1 || $2 || ($& > ?/ ? ?/ : ?\\)
}]
puts s
}

See it on ideone: http://ideone.com/HN0l0Y

• my bad, didn't see that f in the body – Cyoce Aug 24 '16 at 15:03

Batch, 137 bytes

@echo off
if %1==/\ goto g
set s=%1
set s=\%s:~2,-2%/
set s=%s:/=-%
set s=%s:\=/%
set s=%s:-=\%
call %0 %s% "%~2 "
:g
echo %~2%1

Conveniently my use of%~2 and %1 means that I avoid having to spend bytes on setlocal. Explanation: Since Batch won't perform replacements on the empty string, we have to set up the next layer with the "wrong" edges, which will then be corrected as part of the string replacements.

BASH (sed + sort) 71 66 Bytes

sed -rne':l;p;y|\\|1|;y|/|\\|;y|1|/|;th;:h;s|\\.(.*)./| /\1\\|;tl'|sort
sed -rne':l;p;y|\\/|1\\|;y|1|/|;th;:h;s|\\.(.*)./| /\1\\|;tl'|sort

input comes from stdin.
Example:

echo '//\\' |sed -rne':l;p;y|\\|1|;y|/|\\|;y|1|/|;th;:h;s|\\.(.*)./| /\1\\|;tl'|sort

/\
/\\\

Explanation:
-n - suppress auto print
:l - and tl branch back to the beginning if this line was something other than /\
p - print this line
y|\\/|1\\|;y|1|/| - replace \ with 1, / with \, and then 1 with /
th;:h - test and jump the the same place, so that only the next substitution gets tested later
s|\\.(.*)./| /\1\\| - replace the outside two slashed on each side with {space}/ and \
sort - space comes before / so this puts everything in the right order

05AB1E, 4238 36 bytes

Try it online!

Explanation:

# Read the input to the stack, loop for 0 .. len(input) / 2 - 1
Dg;<F
# Save the layer by pushing a copy on the stack, then push
# len(layer) - 2 to both the top of the stack and register_c
# a = pop(); b = pop(); push(b[0:a].reverse())
# This removes the last 2 characters and reverses
£R
# push(register_c - 2 - N)
®ÍN-
# a = pop(); b = pop(); push(b[0:a])
# This removes the leading spaces and the first two slashes
£
# Push "/\" and "\/" to the stack.
„/\Â
# Transliterate the slashes
‡
# Add N+1 spaces and a / to the end of the (reversed) current layer
'/ðN>×««
# Reverse the layer and add a \ to the end.
R'\«
# End the loop
}
# Reverse the stack and join it with newlines. It is implicitly printed.
r»

(Thanks to Emigna for pointing out that DD -> Ð and DR -> Â).

• Dg;GDðK¦¦¨¨„/\Â‡'\«R'/«ðN×«R}r» saves 7 bytes. – Emigna Aug 23 '16 at 17:22
• That looks different enough to me that I think you should add your own answer :). – ruds Aug 23 '16 at 17:30

Go, 300 276 bytes

package main
import(."regexp";."os")
func p(b string)string{
s:=MustCompile(((\s*.)(\S*)(\S))).FindStringSubmatch(b)
if s!=""{r:=""
for _,c:=range s[1:len(s)-1]{r+=\/[c/64:c/46]}
return p(" "+s+r+\)+s+"\n"}
return s+"\n"}
func main(){print(p(Args))}

Long version:

package main

import (
"regexp"
"os"
)

func pyramid(base string) string {
m := regexp.MustCompile(^((\s*\S)(\S*)(\S))\s*).FindStringSubmatch(base)
if len(m) > 0 {
reversed := ""
for _, c := range m[1:len(m) - 1] {
if c == '/' {
reversed += \
} else {
reversed += /
}
}
return pyramid(" " + m + reversed + m) + m + "\n"
}
return m + "\n"
}

func main() {
print(pyramid(os.Args))
}
• import(."regexp";."os") saves 2 bytes – Sefa Aug 22 '16 at 11:34
• @Sefa Thanks, I squeezed another 22 bytes out of it. – Roland Illig Aug 22 '16 at 19:43

Perl, 53 52 bytes

Includes +1 for -p

Run with the input on STDIN, e.g.

./pyramid.pl <<< '//\\///\/\'

pyramid.pl:

#!/usr/bin/perl -p
s%^( *)/.(.*)..%"$1 \\$2/
"=~y|\\/|/\\|r.$&%e&&redo 05AB1E, 31 bytes Dg;GDðK¦¦¨¨„/\Â‡'\«R'/«ðN×«R}r» Explanation Dg;G } # for N in [1..len(input)/2-1] D # make a copy of previous layer ðK # remove all spaces ¦¦¨¨ # remove first 2 and last 2 chars „/\Â‡ # replace '/' with '\' and vice versa '\« # add a backslash at the end R # reverse '/« # ad a slash at the end ðN×« # add N spaces R # reverse back r» # reverse stack and join on newline # implicitly print Try it online ><>, 186179175 171 bytes 0&v &+1&< >i:0)?^~&2,:&v v'/'~v?:-1< }0< o >84*o^-$;?=@:&:&}:~<
\&::&{:@+$}1+[{l1-$-2*:&1+{
>}1-:?!v$:l2%?!vo ^o'/'v?~e (*5a< ^o'\'< & >~]a'\'oo{1+:^ {$1- >:?!^

oooh man this is definitely my largest ><> answer yet.

There's still probably some golfing left to be done (the bottom area is pretty wasteful)

Try it online

Powershell, 142 bytes

function s($s){if($s.Trim()-eq'/\'){return $s}$n=$s-replace'\\','#'-replace'/','\'-replace'#','/'-replace'\\.(.*)./',' /$1\'
(s($n))+"`n$s"
}

C#, 250 bytes

s=>{int j=s.Length/2,i=0;var l=new string[j];l[j-1]=s;while(++i<j){var n=l[j-i].Trim().Substring(1,l[j-i].Trim().Length-2);l[j-i-1]=new string(' ',i)+"/"+n.Replace("/","#").Replace(@"\","/").Replace("#",@"\").Substring(1,n.Length-2)+@"\";}return l;};

Can definitely be golfed further but my brain went dead so I decided to leave it as it is for the moment.