25
\$\begingroup\$

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.

The task

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!

\$\endgroup\$
1

18 Answers 18

12
\$\begingroup\$

Retina, 59 56 54 52 bytes

{`^( *)/.(.*)..
$1 /$2\¶$0
T`/\\`Ro`(?<=^ +/).+(?=.)

Try it online!

Sample output

    /\
   /\\\
  /\///\
 ///\\\/\
//\\///\/\
\$\endgroup\$
1
11
\$\begingroup\$

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

Test Suite.

\$\endgroup\$
9
\$\begingroup\$

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

\$\endgroup\$
8
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ Clever using translate, but do we not have to print? \$\endgroup\$ Commented Aug 20, 2016 at 20:40
  • \$\begingroup\$ @JonathanAllan Not by default, you just have to output as the challenge says. \$\endgroup\$
    – xnor
    Commented Aug 20, 2016 at 20:42
7
\$\begingroup\$

Haskell, 98 94 90 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!

\$\endgroup\$
3
  • \$\begingroup\$ l++"\\\n" looks like l#"". \$\endgroup\$
    – xnor
    Commented Aug 20, 2016 at 20:45
  • 1
    \$\begingroup\$ An interesting way to swap two characters in a string s is [c|x<-s,c<-"ab",c/=x]. \$\endgroup\$
    – xnor
    Commented Aug 20, 2016 at 20:53
  • \$\begingroup\$ @xnor: I've tried many things to get rid of the second ++"\\\n", but missed this one. Thanks! \$\endgroup\$
    – nimi
    Commented Aug 20, 2016 at 21:05
6
\$\begingroup\$

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).

\$\endgroup\$
2
  • \$\begingroup\$ You can jointly declare f,b='/\\' outside the function. \$\endgroup\$
    – xnor
    Commented Aug 20, 2016 at 21:00
  • \$\begingroup\$ @xnor Thanks, I can't count ^^ \$\endgroup\$ Commented Aug 20, 2016 at 21:11
5
\$\begingroup\$

JavaScript (ES6), 91 86 bytes

f=
(s,t=`
`)=>s[2]?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.

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

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

\$\endgroup\$
1
  • \$\begingroup\$ my bad, didn't see that f in the body \$\endgroup\$
    – Cyoce
    Commented Aug 24, 2016 at 15:03
3
\$\begingroup\$

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.

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

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

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

05AB1E, 42 38 36 bytes

Dg;<FÐgÍ©£R®ÍN-£„/\‡'/ðN>׫«R'\«}r»

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
     ÐgÍ©
# 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 -> Â).

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

Go, 300 276 bytes

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

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[3]) > 0 {
        reversed := ""
        for _, c := range m[3][1:len(m[3]) - 1] {
            if c == '/' {
                reversed += `\`
            } else {
                reversed += `/`
            }
        }
        return pyramid(" " + m[2] + reversed + m[4]) + m[1] + "\n"
    }
    return m[1] + "\n"
}

func main() {
    print(pyramid(os.Args[1]))
}
\$\endgroup\$
2
  • \$\begingroup\$ import(."regexp";."os") saves 2 bytes \$\endgroup\$
    – Sefa
    Commented Aug 22, 2016 at 11:34
  • \$\begingroup\$ @Sefa Thanks, I squeezed another 22 bytes out of it. \$\endgroup\$ Commented Aug 22, 2016 at 19:43
1
\$\begingroup\$

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

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

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

><>, 186 179 175 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

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

Powershell, 142 bytes

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

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.

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

Stax, 22 bytes

à╝á■╬h½₧£Hδuóß►Δ䣃┐#R

Run and debug it

\$\endgroup\$

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.