15
\$\begingroup\$

You will be given a String consisting of printable ASCII (without newlines). Your task is to build a nice Stairway for my Castle.

How to build a nice Stairway?

  • First off, you should get all the rotations of the String. For example, the String abcd has the following rotations: abcd, bcda, cdab, dabc (each character is moved to the end until we reach the last character).

  • We now place each rotation on top of each other:

    abcd
    bcda
    cdab
    dabc
    
  • We can't really climb on a straight wall, so we must build stairs. That means you should add a number of spaces before each rotation corresponding to its index in the rotation list:

    abcd
     bcda
      cdab
       dabc
    
  • You also need a Stairway that links to the other side of my castle, so you should build one like below, reversing each rotation and adding some spacing:

    abcd      dcba
     bcda    adcb
      cdab  badc
       dabccbad
    

This is , hence the shortest code in bytes wins and standard rules for the tag apply.


Test Cases

  • Input: abcd, Output:

    abcd      dcba
     bcda    adcb
      cdab  badc
       dabccbad
    
  • Input: aaaa, Output:

    aaaa      aaaa
     aaaa    aaaa
      aaaa  aaaa
       aaaaaaaa
    
  • Input: Code golf, Output (Notice the spaces):

    Code golf                flog edoC
     ode golfC              Cflog edo 
      de golfCo            oCflog ed  
       e golfCod          doCflog e   
         golfCode        edoCflog     
         golfCode        edoCflog     
          olfCode g    g edoCflo      
           lfCode go  og edoCfl       
            fCode gollog edoCf
    
\$\endgroup\$
5
  • \$\begingroup\$ Sandbox \$\endgroup\$
    – Mr. Xcoder
    Commented Jul 22, 2017 at 18:30
  • \$\begingroup\$ Shouldn't the stairway start going up, and then go down, instead of going down, then up? :P \$\endgroup\$
    – Stephen
    Commented Jul 22, 2017 at 18:36
  • \$\begingroup\$ @StepHen For the purpose of this challenge, it shouldn't :p \$\endgroup\$
    – Mr. Xcoder
    Commented Jul 22, 2017 at 18:36
  • 6
    \$\begingroup\$ Closely related \$\endgroup\$
    – DJMcMayhem
    Commented Jul 22, 2017 at 18:46
  • 1
    \$\begingroup\$ dabc. ------- \$\endgroup\$
    – Oliver Ni
    Commented Jul 25, 2017 at 8:23

22 Answers 22

10
\$\begingroup\$

05AB1E, 12 bytes

Code:

vDNúsÀ}\».B∞

Uses the 05AB1E encoding. Try it online!

Explanation:

v     }        # Length input times, do.. (N = iteration count)
 DNú           #   Duplicate and prepend N spaces
    sÀ         #   Swap and rotate one to the left
       \       # Discard the top of the stack
        »      # Join the stack by newlines
         .B    # Pad with spaces into a rectangle
           ∞   # Mirror the string
\$\endgroup\$
1
4
\$\begingroup\$

Jelly, 16 bytes

J’ɓ⁹⁶ẋ;"ṙz⁶Zm€0Y

Try it online!

Of course, -1 using Jonathan Allan's ɓ!

\$\endgroup\$
2
  • \$\begingroup\$ My solution is too similar methinks, here you go: J’ɓ⁹⁶ẋ;"ṙz⁶Zm€0Y (or LḶ for J’) \$\endgroup\$ Commented Jul 22, 2017 at 19:20
  • \$\begingroup\$ @JonathanAllan Heh. \$\endgroup\$ Commented Jul 23, 2017 at 7:27
4
\$\begingroup\$

Python 3, 85 bytes

x=input()
l=len(x)
for i in range(l):y=x[i:]+x[:i];print(' '*i+y+'  '*(l+~i)+y[::-1])

Try it online!

-1 byte thanks to ovs
-1 byte thanks to Lynn
-4 bytes thanks to p1131

\$\endgroup\$
3
  • \$\begingroup\$ l-i-1 can just be l+~i as ~i == -i-1 \$\endgroup\$
    – ovs
    Commented Jul 22, 2017 at 21:03
  • \$\begingroup\$ ' '*(l+~i)*2 equals '  '*(l+~i), which is one byte shorter! \$\endgroup\$
    – lynn
    Commented Jul 22, 2017 at 23:05
  • \$\begingroup\$ You can save 4 bytes by ommiting the assignment to j and putting the expression directly in the print()! Try it online! \$\endgroup\$
    – pan
    Commented May 22, 2021 at 4:06
3
\$\begingroup\$

Retina, 47 bytes

.
$.`$* $&$'$`$.'$* ¶
%(`^
$_¶
O$^`.(?=.*$)

¶

Try it online! Explanation: The first stage creates the left stairway by considering each character and creating spaces equal to the current position, then the remainder of the string, then the start of the string, then spaces equal to the remainder of the string. The rest of the script runs over each line just generated in turn. First the line is duplicated, then the characters in the duplicate are reversed, then the line and its duplicate are concatenated.

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

J, 27 bytes

[:(,.|.)i.@#(|.,~' '#~[)"{]

Try it online!

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

C (gcc), 126 bytes

i,j,k,l;f(char*s){for(l=strlen(s),i=0;i<l;i++,puts(""))for(j=0;j<4*l-2;j++,putchar(i<=k&k<i+l?s[k%l]:32))k=j<2*l-1?j:4*l-3-j;}

Try it online!

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

Charcoal, 23 21 20 bytes

FLθ«FLθ§θ⁺κι↘MLθ←»‖C

Try it online!

Can probably be golfed more, but I'm posting from the mobile app. Link to the verbose version.

\$\endgroup\$
4
  • \$\begingroup\$ Oh btw if you don't add an explanation at least use -a flag pls \$\endgroup\$
    – ASCII-only
    Commented Jul 26, 2017 at 22:16
  • \$\begingroup\$ @ASCII-only sorry, I thought the verbose version counted as an explanation. \$\endgroup\$
    – Charlie
    Commented Jul 27, 2017 at 6:06
  • \$\begingroup\$ Wait what nvm didn't see that \$\endgroup\$
    – ASCII-only
    Commented Jul 27, 2017 at 6:44
  • \$\begingroup\$ I don't think it was true at the time but these days you can fill a polygon with an arbitrary string and get exactly the result you need for 9 bytes: G→↘←Lθθ‖C. \$\endgroup\$
    – Neil
    Commented Dec 2, 2017 at 13:26
2
\$\begingroup\$

Haskell, 80 79 bytes

(s:u)#t|q<-(t>>" ")++s:u++t++(u>>" ")=q++reverse q++'\n':u#(t++[s])
u#_=u
(#"")

Try it online!

How it works

(#"")                      -- start with the input string and an empty accumulator

(s:u)#t                    -- let s be the first char and u the rest of the input
                           -- string, and t the accumulator
    |q<-                   -- let q be half of the current line, i.e.
        (t>>" ")++         --   length of t times spaces
        s:u++              --   s and u (aka the input string)
        t++                --   the accumulator
        (u>>" ")           --   length of u times spaces
    = q ++ reverse q ++    -- the current line is q and q reversed
        '\n' :             -- and a newline
        u#(t++[s])         -- and a recursive call with u as the new input
                           -- string and s put at the end of t
_#_=[]                     -- base case: stop if the input string is empty

Edit: Thanks to @Ørjan Johansen for a byte.

\$\endgroup\$
2
  • \$\begingroup\$ u#_=u saves a byte. \$\endgroup\$ Commented Jul 23, 2017 at 3:53
  • \$\begingroup\$ @ØrjanJohansen: I first had a list of strings and unlines where u#_=u does not type check and later switched to building a single string ... Thanks! \$\endgroup\$
    – nimi
    Commented Jul 23, 2017 at 3:59
2
\$\begingroup\$

Vyxal, 26 24 23 20 bytes

L(DL‹n-ð$*+mðn*$+,1Ǔ

Try it Online!

Thanks to lyxal for -3 bytes

\$\endgroup\$
1
  • \$\begingroup\$ Try it Online! for 20 \$\endgroup\$
    – lyxal
    Commented May 25, 2021 at 11:57
1
\$\begingroup\$

Pyth, 19 bytes

jms_BdC.tm+*d;.<QdU

Try it online!

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

Mathematica, 119 bytes

b=StringRotateLeft;j=Table;Column@j[""<>{" "~j~i,b[s=#,i],j["  ",t-i],b[StringReverse@s,-i]},{i,0,t=StringLength@#-1}]&
\$\endgroup\$
1
\$\begingroup\$

PHP, 95 bytes

for($e=strlen($s=$argn);$i<$e;$s.=$s[$i],$s[$i++]=" ")echo$t=str_pad($s,2*$e-1),strrev($t),"
";

Run as pipe with -nR or try it online.

breakdown

for($e=strlen($s=$argn);    # import input
    $i<$e;                  # loop length times
    $s.=$s[$i],                 # 2. append current character
    $s[$i++]=" ")               # 3. set current character to space
    echo$t=str_pad($s,2*$e-1),  # 1. print string padded with length-1 spaces
        strrev($t),             #    print reverse
        "\n";                   #    print newline
\$\endgroup\$
1
\$\begingroup\$

Japt, 22 bytes


l
VÇç +UéZn)+´Vç)ê1÷

Leading newline is part of the program.

Try it online!

Run all test cases using my WIP CodePen.

Explanation

Implicit: U = input string. First line is blank to not overwrite U.

Second line implicitly assigns the length (l) of U to V.

Third line:

VÇç +UéZn)+´Vç)ê1÷
VoZ{Zç +UéZn)+--Vç)ê1} · Ungolfed
VoZ{                 }   Create array [0, V) and map by...
    Zç                      The current value (Z) times " "
       +UéZn)               Concatenated with U rotated Z times left
             +--Vç)         Concatenated with --V times " ". This decrements V
                   ê1       Palindromize with repeated last char
                       · Join with newlines and implicitly output
\$\endgroup\$
1
\$\begingroup\$

Pyth, 20 bytes

jms_B.>+.<Qd*\ tlQdl

Try it online!

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

Javascript (ES6), 118 bytes

s=>[...s].map((_,y)=>Array(l=(j=s.length)*4-2).fill().map((_,x)=>(x=x<l/2?x:l-x-1)>=y&y+j>x?s[x%j]:" ").join``).join`
`

Example code snippet:

f=
s=>[...s].map((_,y)=>Array(l=(j=s.length)*4-2).fill().map((_,x)=>(x=x<l/2?x:l-x-1)>=y&y+j>x?s[x%j]:" ").join``).join`
`
o.innerText=f("Code golf")
<pre id=o>

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

Python 2, 85 83 bytes

  • Thanks @ovs for 2 bytes: l+~i and helped me spot a unwanted space
x=input()
l=len(x)
for i in range(l):r=i*' '+x[i:]+x[:i]+(l+~i)*' ';print r+r[::-1]

Try it online!

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

8th, 173 168 bytes

Code

s:len n:1- ( >r dup s:len n:1- "" ( " " s:+ ) rot times dup 0 r@ s:slice -rot r> -1 s:slice s:+ s:+ dup s:rev swap . . cr null s:/ a:shift a:push "" a:join ) 0 rot loop

Ungolfed version with comments

: shifter \ s -- s
  null s:/     \ convert string into array
  a:shift      \ remove the first item in the array and put it on TOS
  a:push       \ append the former 1st item to array
  "" a:join    \ convert array into string
;

: stairway \ s -- s
  s:len n:1-
  (
    >r                       \ save loop index
    dup                      \ duplicate input string 
    s:len n:1-               \ get string length
    "" ( " " s:+ ) rot times \ make filler
    dup                      \ duplicate filler 
    0 r@ s:slice             \ make left filler
    -rot                     \ put left filler at proper position
    r> -1 s:slice            \ make right filler
    s:+ s:+                  \ build string ( 1st half of stairway )
    dup s:rev                \ build 2nd half 
    swap . . cr              \ print it
    shifter                  \ shift rotate 1st character
  ) 0 rot loop               \ loop from 0 to len(string)-1
;

Usage and examples

ok> "abcd" s:len n:1- ( >r dup s:len n:1- "" ( " " s:+ ) rot times dup 0 r@ s:slice -rot r> -1 s:slice s:+ s:+ dup s:rev swap . . cr null s:/ a:shift a:push "" a:join ) 0 rot loop
abcd      dcba
 bcda    adcb 
  cdab  badc  
   dabccbad 

Or more clearly

ok> "Code golf" stairway
Code golf                flog edoC
 ode golfC              Cflog edo 
  de golfCo            oCflog ed  
   e golfCod          doCflog e   
     golfCode        edoCflog     
     golfCode        edoCflog     
      olfCode g    g edoCflo      
       lfCode go  og edoCfl       
        fCode gollog edoCf 
\$\endgroup\$
1
\$\begingroup\$

APL (Dyalog Unicode), 29 bytes

{w←⍵⋄(⊢,⌽)↑{(-⍵+⍴w)↑⍵⌽w}¨⍳⍴⍵}

Try it online!

Explanation

{w←⍵⋄(⊢,⌽)↑{(-⍵+⍴w)↑⍵⌽w}¨⍳⍴⍵} ⍵ → input
 w←⍵                          assign original input to w
                         ⍳⍴⍵  range from 0 to length of ⍵
           {           }¨     map range to function, loop var i
                    ⍵⌽w       input rotated i characters
            (-⍵+⍴w)           i + length of input, negated
                   ↑          take that much from the rotated string
                              (prepends spaces)
          ↑                   mix the array to create one side of the pattern
     (⊢,⌽)                    append the reverse of the matrix to itself 
\$\endgroup\$
1
\$\begingroup\$

Perl 5 + -lF -M5.10.0, 57 bytes

@F=@F[1..$#F,!say$"x$-,@F,"  "x($#F-$-++),reverse@F]for@F

Try it online!

Explanation

Using -F (specifying the -F switch without an argument, -F controls how a string is split into @F) the input is split into a list of singular chars. for each char in @F, @F is then set to the slice of index 1 to $#F (which is the last index in @F) followed by the item at index !say... which equates to 0. The effectively shifts the list content backwards by one index each iteration. say is called within the indexing operation to produce the output before the list is re-indexed and is provided with $"x$- ($-, which is a special int only variable that is preinitialised to 0, copies of $", which is the special list separator variable, preinitialised to space) followed by @F, followed by " "x($#F-$-++) (two spaces repeated by the final index of @F with the current value of $- times - $- is post-incremented here so will increase on the next iteration), finally followed by the reverse of @F.

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

Python 2, 82 bytes

x=input()
i=l=-len(x)
while i:s=x[i:]+x[:i];i+=1;print' '*(~l+i)+s+'  '*-i+s[::-1]

Try it online!

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

Pip -l, 21 bytes

aMERF:sX#aRA_a@Y_+,#a

Try it online!

Explanation

                       a is command-line argument; s is space (implicit)
aME                    Map this function to each number in 0 .. len(a)-1:
                  ,#a   Range(len(a))
                _+      Add the function's argument: Range(_, _+len(a))
               Y        Yank that range (just to get the precedence right)
             a@         Use the range as the (modular) indices to slice into the string
      sX#a              Get a string of spaces of the same length as the input string
          RA_           Replace the space at index _ with the slice calculated above
   RF:                  Reflect the string, appending its reverse to it
                       Output the result list one item per line (-l flag)
\$\endgroup\$
0
\$\begingroup\$

Japt -R, 15 bytes

¬£éYn)iYçÃú mê1

Try it

¬£éYn)iYçÃú mê1     :Implicit input of string U
¬                   :Split
 £                  :Map each character at 0-based index Y
  é                 :  Rotate U right
   Yn               :    -Y times
     )              :  End rotate
      i             :  Prepend
       Yç           :    Space repeated Y times
         Ã          :End map
          ú         :Right pad with spaces to the length of the longest
            m       :Map
             ê1     :  Mirror
                    :Implicit output joined with newlines
\$\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.