16
\$\begingroup\$

Given a string, your task is to collapse it into a zigzag-like structure as described below.

Folding into a Zigzag

We'll take the string "Mississippi" as an example:

  1. First, output the longest prefix consisting of unique characters only:

    Mis
    
  2. When you reach the first duplicate character C, ignore it, and output the longest prefix consisting of unique characters of the remaining string (issippi) vertically, below the first occurrence of C:

    Mis
      i
      s
    
  3. Repeat the process, alternating between horizontal and vertical continuation. But now be careful (at step 1) to continue outputting horizontally from latest occurrence of the duplicate character, which is not necessarily the last one, as in this case:

    Mis
      i
      sip
    -----
    Mis
      i
      sip
        i
    

Rules

  • The string will only contain printable ASCII characters, but won't contain any kind of whitespace.
  • You can compete in any programming language and can take input and provide output through any standard method and in any reasonable format1, while taking note that these loopholes are forbidden by default. This is , so the shortest submission (in bytes) for every language wins.
  • 1 Input: String / List of characters / whatever else your language uses to represent strings. Output: Multiline string, list of strings representing lines or list of lists of characters/length-1 strings, but please include a pretty-print version of your code in your answer, if possible.
  • Regarding additional spaces, the output may contain:
    • Leading / trailing newlines
    • Trailing spaces on each line / at the end
    • A consistent number of leading spaces on each line
  • You must begin to output horizontally, you may not start vertically.

Test cases

Inputs:

"Perfect"
"Mississippi"
"Oddities"
"Trivialities"
"Cthulhu"
"PPCG"
"pOpOpOpOpOpOp"
"ABCCCE"
"ABCCCECCEEEEC"
"abcdcebffg"
"abca"
"AAAAAAAA"

Corresponding outputs:

Perf
 c
 t
Mis
  i
  sip
    i
Od
 ies
 t
Triv
  a
  l
  ies
  t
Cthul
  u
P
C
G
pO 
OpO
pOp
 p
ABC
  C
  E
ABC
  CCE
  E EC
abcd
  e
  b
  fg
abc
A
AA
 A
\$\endgroup\$
  • \$\begingroup\$ @JungHwanMin Because you should't jump back to the first b, as you should only consider duplicates in the remaining string, that is, after "branching". Once you reach the second c, you output the longest prefix of unique chars of the remaining string, which is ebffg (thus outputting ebf vertically and continuing horizontally after that), so you don't have to worry about the characters from the part of the string that was already outputted before switching orientation. If it still feels unclear to you, I'll make another step-by-step example with this test case. \$\endgroup\$ – Mr. Xcoder Jun 20 '18 at 14:19
  • \$\begingroup\$ How should we handle lower/upper case? For example ABCcde \$\endgroup\$ – Rod Jun 20 '18 at 14:32
  • \$\begingroup\$ You should treat them as different characters. E.g "A" ≠ "a". The output for ABCcde would just be ABCcde \$\endgroup\$ – Mr. Xcoder Jun 20 '18 at 14:33
  • \$\begingroup\$ Test case suggestion: AAAAAAAA \$\endgroup\$ – JungHwan Min Jun 20 '18 at 15:03
  • 5
    \$\begingroup\$ @JungHwanMin AAAAAAAAdded that one too. \$\endgroup\$ – Mr. Xcoder Jun 20 '18 at 15:06
2
\$\begingroup\$

Wolfram Language (Mathematica), 143 bytes

{#}//.{q___,a_,r___,a_,Longest@s___}:>{q}~f@{a,r}~{{s}}//.{q_~f@a_~s_}/;s~FreeQ~f:>(PadLeft@{q~Join~#,##2}&)@@PadRight@Join[{a},s]/. 0->" "&

Try it online!

Contains 0xF8FF, which corresponds to the \[Transpose] operator.

Phew, it was tough making the result into a string. Getting each branch isn't so tough: #//.{q___,a_,r___,a_,Longest@s___}:>{q,a,{r},{s}}&

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

Python 2, 131 bytes

X=Y=y=0
s=input()
o=()
l={}
for i in s:o+=[' ']*len(s),;exec('l[i]=X,Y','y^=1;X,Y=l[i];l={}')[i in l];o[Y][X]=i;X+=y<1;Y+=y
print o

Try it online!

-1 thanks to Lynn.

Prints as a tuple of lists of length-1 strings. Pretty-printed output.

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

Python 2, 184 176 175 168 bytes

-5 bytes thanks to Mr. Xcoder

def f(x):i,k=[p for p in enumerate(map(x.find,x+"z"))if cmp(*p)][0];return[x[:i]+' '*len(x)]+[' '*k+''.join(d)+i*' 'for d in zip(*f(x[i+1:]))]if x[len(set(x)):]else[x,]

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I don't think the latest save is valid; what if the input contains \? Also, you can output as a list of lists of length-1 strings, as I do in my solution, per the OP. \$\endgroup\$ – Erik the Outgolfer Jun 20 '18 at 18:55
  • \$\begingroup\$ @EriktheOutgolfer same byte count :c \$\endgroup\$ – Rod Jun 20 '18 at 19:04
0
\$\begingroup\$

CJam, 81 bytes

{_,_S*a*a\+{__L#){V!:V;L#)LM:L;=~:U;:T}{[TU]a+L+:L}?;U@_U=T4$tt\;TV!+:T;UV+:U;}*}

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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