Draw diagonal lines of text

46

2

Given an input of a list of words, output the words with their letters arranged diagonally:

p
 r
  o
p  g
 u  r
  z  a
a  z  m
 n  l  m
  d  e  i
c     s  n
 o        g
  d
g  e
 o
  l
   f

(The above should be the output for the input programming puzzles and code golf.)

To be precise, each word starts on the first column and three rows below the previous word, and each successive letter moves one column to the right and one row down.

The input may be provided as either a single string of words, separated by exactly one space, or a list/array of words. The words will only be composed of lowercase letters, a-z, and will always be at least one character long.

The output may be a single string, an array of lines, or an array of arrays of characters. Leading or trailing whitespace is not allowed, except for a single trailing newline.

Further test cases:

a bcd efgh i j

a


b
 c
  d
e
 f
  g
i  h


j

x

x

verylongword short

v
 e
  r
s  y
 h  l
  o  o
   r  n
    t  g
        w
         o
          r
           d

Since this is , the shortest code in bytes will win!

Doorknob

Posted 2016-11-13T22:53:06.900

Reputation: 68 138

I feel like I should be able to make a Python program for this in 5 minutes, but it always seems to be failing... ;_; – HyperNeutrino – 2016-11-14T03:58:27.453

Wow, it seems like there are a lot of challenges seemingly designed for Turtlèd – Destructible Lemon – 2016-11-15T01:01:13.687

Are terminal escape codes allowed? :) – Chromium – 2018-06-28T09:30:33.507

Answers

17

Vim, 85, 76, 66, 52 keystrokes/bytes

When I first looked at this challenge, I thought "This is perfect for vim!" And then when I tried it everything went wrong. Here it is, in all of it's messy hacky glory:

:se ve=all|s/ /\r\r\r/g
qqGo<esc>?\<.\S
lDjP@qq@qG?.
jdG

Try it online, thanks to the (mostly) backwards compatible V interpreter.

Explanation:

At first I thought I could do this beautifully simple 37 byte version:

:se ve=all
qq:g/\S\S/norm ^lDjP
@qq@q

Unfortunately, it's not that simple. Let's take it line by line:

:se ve=all

This enables a feature called 'virtual editing'. It allows the cursor to move to columns that don't exist yet. This answer would be basically impossible without it.

Now we need to separate out the words onto different lines. So we'll replace each space with 3 newlines. Since this is an ex command we can run it simultaneously with our last ex command :se ve=all by seperating the two with a bar.

|s/ /\r\r\r/g

Now the buffer looks like this:

Programming


Puzzles


and


code-golf

Here's where the fun begins. We set up the traditional recursive macro with: qq, and then call this:

G               " Move to the last line
 o<esc>         " Append an extra newline

?               " Search backwards for
 \<.            " Any character at the beginning of a word
    \S          " Followed by a non-space character
l               " Move one character to the right
 D              " Delete eveything until the end of this line
  j             " Move down one line
   P            " Paste what we just deleted

Then we finish the recursive macro with @qq@q. At this point, we have all of the diagonals, we just need to do a little clean up.

G                   " Move to the last line
 ?.                 " Search backwards for any character
j                   " Move down one line
 dG                 " Delete until the end of the buffer

James

Posted 2016-11-13T22:53:06.900

Reputation: 54 537

Wow, JavaScript is (currently) shorter than Vim. That's quite a rare occurence these days... – ETHproductions – 2016-11-14T02:30:26.937

@ETHproductions Not any more. :) – James – 2016-11-14T03:04:18.160

6

Turtlèd, 28 26 bytes

Oh my, I appear to be beating a language specifically designed for golfing. this is a great day.

!_4[*.[ rd+.]ul[ ul]r;_+]_

Try it online!

Explanation

(write means writing to the cell on the grid, pointed char means char in input the string pointer points to)

!                         Take string input into variable
 _                        Normally conditional, with >1 input (there will be), write ' '
  4                       set register to 4
   [*                   ] until the current cell is *
     .                    Write pointed char, initially first char
      [     ]             Until space is written on cell
        rd+.              move right, down, string pointer++, write pointed char
             ul[ ul]      Move back up to the top of the word
                    r;    Move right, down 4 (because this is register value)
                      _+  write * if end of input, else ' ', increment string pointer
                        _ will always write ' ', since it will always point at start char

note trailing space.

Input also needs trailing space. seeing as python can take a list, this is a lot like taking a list in Turtlèd

Destructible Lemon

Posted 2016-11-13T22:53:06.900

Reputation: 5 908

5

MATL, 28 bytes

c!t&n:q3_*ts_b+5M4$XdZ!cZ{Zv

Input is a cell array of strings, with commas as optional separators:

{'programming' 'puzzles' 'and' 'code' 'golf'}

or

{'programming', 'puzzles', 'and', 'code', 'golf'}

Try it online! Or verify all test cases: 1, 2, 3, 4.

Explanation

Consider the following input as an example:

{'aaaa' 'bb' 'ccc'}

You can view the partial results (stack contents) inserting the comment symbol % at any point in the code. For example, view the stack contents after the fourth function (&n).

c        % Input cell array of strings implicitly. Convert to 2D char array,
         % right-padding with spaces
         % STACK: ['aaaa'; 'bb  '; 'ccc']
!        % Transpose
         % STACK: ['abc'
                   'abc'
                   'a c'
                   'a  ']
t        % Duplicate
         % STACK: ['abc'
                   'abc'
                   'a c'
                   'a  '],
                  ['abc'
                   'abc'
                   'a c'
                   'a  '],
&n       % Number of rows and of columns
         % STACK: ['abc'
                   'abc'
                   'a c'
                   'a  '], 4, 3
:q       % Range, subtract 1
         % STACK: ['abc'
                   'abc'
                   'a c'
                   'a  '], 4, [0 1 2]
3_*      % Multiply by -3
         % STACK: ['abc'
                   'abc'
                   'a c'
                   'a  '], 4, [0 -3 -6]
ts_      % Duplicate, sum, negate
         % STACK: ['abc'
                   'abc'
                   'a c'
                   'a  '], 4, [0 -3 -6], 9
b        % Bubble up in stack
         % STACK: ['abc'
                   'abc'
                   'a c'
                   'a  '], [0 -3 -6], 9, 4
+        % Add
         % STACK: ['abc'
                   'abc'
                   'a c'
                   'a  '], [0 -3 -6], 13
5M       % Push second input of last function again
         % STACK: ['abc'
                   'abc'
                   'a c'
                   'a  '], [0 -3 -6], 13, 4
4$Xd     % Buld numerical sparse matrix from the above four arguments. The
         % columns of the first input argument will be the diagonals of the
         % result, with indices given bu the second input (negative is below
         % main diagonal). The matrix size is the third and fourth arguments
         % STACK: [97  0  0  0
                    0 97  0  0
                    0  0 97  0
                   98  0  0 97
                    0 98  0  0
                    0  0 32  0
                   99  0  0 32
                    0 99  0  0
                    0  0 99  0
                    0  0  0 32
                    0  0  0  0
                    0  0  0  0
                    0  0  0  0]
Z!c      % Convert from sparse to full, and then to char. Character 0 is
         % displayed as space
         % STACK: ['a   '
                   ' a  '
                   '  a '
                   'b  a'
                   ' b  '
                   '    '
                   'c   '
                   ' c  '
                   '  c '
                   '    '
                   '    '
                   '    '
                   '    ']
Z{       % Split into cell array, with each row in a cell
         % STACK: {'a   ', ' a  ', '  a ', 'b  a', ' b  ', '    ', 'c   ', ' c  ', '  c ', '   ', '   ', '   ', '   '}
Zv       % Deblank: remove trailing space from each string. Implicitly display,
         % each string on a different line. Empty strings do not generate
         % a newline
         % STACK: {'a   ', ' a', '  a', 'b  a', ' b', '', 'c', ' c', '  c', '', '', '', ''}

Luis Mendo

Posted 2016-11-13T22:53:06.900

Reputation: 87 464

4

JavaScript (ES6), 118 109 84 bytes

Takes input as an array of words. Returns an array of arrays of characters.

s=>s.map((w,y)=>[...w].map((c,x)=>(a[p=y*3+x]=a[p]||Array(x).fill(' '))[x]=c),a=[])&&a

Alternative version, 109 bytes

Returns a string.

let f =

s=>s.map((w,y)=>[...w].map((c,x)=>(a[p=y*3+x]=a[p]||Array(x).fill` `)[x]=c),a=[])&&a.map(s=>s.join``).join`
`

console.log(f(["programming", "puzzles", "and", "code", "golf"]))

Arnauld

Posted 2016-11-13T22:53:06.900

Reputation: 111 334

2

Common Lisp, 673 668 597 bytes

Terrible solution, I know. I'll probably edit this more after some sleep.

(defun f(&rest z)(let((l)(a 0)(s)(o)(b)(c 0))(loop(setf b(length l))(setf l"")(loop for w in z for i from 0 do(if(>(+(length w)(* i 3))c)(setf c(+(length w)(* i 3))))(setf s(+(* i -3)a))(when(and(>= s 0)(< s(length w)))(setf o(format nil"~v@{~a~:*~}"s" "))(if(and(>=(- s 3)0)(not(equal i(-(length z)1))))(setf o(subseq o(- s 2))))(setf l(concatenate'string o(string(char w s))l)))(when(>= s(length w))(setf l(concatenate'string"   "l))))(if(<=(length l)b)(setf l(concatenate'string(format nil"~v@{~a~:*~}"(- b(length l)-1)" ")l)))(print(string-right-trim" "l))(if(>= b c)(return))(setf a(1+ a)))))

Usage:

* (f "ppcg" "is" "pretty" "ok")

"p" 
" p" 
"  c" 
"i  g" 
" s" 
"" 
"p" 
" r" 
"  e" 
"o  t" 
" k  t" 
"     y" 
""
NIL

This loops over every word in the provided list and adds appropriate characters to the current line. Appropriate padding is provided by my subpar usage of format.

Note: I'm new to Common Lisp, but I know enough to realize that this could use a lot of improvement.

artificialnull

Posted 2016-11-13T22:53:06.900

Reputation: 481

2ockquote>

:( "ppcg ... ok"!?

– Destructible Lemon – 2016-12-03T13:47:40.003

2

Python 2, 146 bytes

s=input()
k=max(map(len,s))
a=[k*[' ']for x in range(k+len(s)*3+3)]
for x in range(len(s)):
 for y in range(len(s[x])):a[x*3+y][y]=s[x][y]
print a

Note: the indentations for the last two lines are <space> and <tab>, which saves one byte since I don't need to double-indent.

Input is to be entered as an array of strings like so: ["hello", "world"] or ['hello', 'world']. Output is an array of arrays of characters.

There's probably a better way to do this...

EDIT Thanks to Doorknob for pointing out a missing close square bracket. I placed it before the *k... in the third line.

HyperNeutrino

Posted 2016-11-13T22:53:06.900

Reputation: 26 575

There's a syntax error in your code on the third line; there's two open brackets but only one close bracket. However I fix it (either by adding an extra closing bracket or removing the extra opening bracket), the program gives an error when run. – Doorknob – 2016-11-15T01:10:54.600

This now appears to output trailing whitespace at the ends of lines and at the end of the output, which is not allowed by the challenge specification. – Doorknob – 2016-11-16T03:57:40.403

trivial golfs – Leaky Nun – 2017-06-23T16:58:17.217

@LeakyNun Thanks. Are you just going through and golfing all of my answers? :P – HyperNeutrino – 2017-06-23T17:04:08.283

2

C#, 336 Bytes:

Golfed:

string D(string[]s){int x=0,y=0,r=0,q=2*(s.Max().Length+s.Length)+1;var a=new char[q, q];for(int i=0;i<s.Length;i++){y=r;for(int j=0;j<s[i].Length;j++){a[y,x]=s[i][j];x+=1;y+=1;}x=0;r+=3;}var o="";for(x=0;x<q;x++){var t="";for(y=0;y<q;y++)t+=a[x,y];o+=t==string.Join("",Enumerable.Repeat('\0',q))?"":(t.TrimEnd('\0')+"\r\n");}return o;}

Ungolfed:

public string D(string[] s)
{
  int x = 0, y = 0, r = 0, q = 2 * (s.Max().Length + s.Length) + 1;
  var a = new char[q, q];
  for (int i = 0; i < s.Length; i++)
  {
    y = r;
    for (int j = 0; j < s[i].Length; j++)
    {
      a[y, x] = s[i][j];
      x += 1;
      y += 1;
    }
    x = 0;
    r +=3;
  }
  var o = "";
  for (x = 0; x < q; x++)
  {
    var t = "";
    for (y = 0; y < q; y++)
      t += a[x, y];
    o += t == string.Join("", Enumerable.Repeat('\0', q)) ? "" : (t.TrimEnd('\0') + "\r\n");
  }
  return o;
}

Testing:

  var codeGolf = new DrawDiagonalLinesOfText();
  Console.WriteLine(codeGolf.E(new string[] { "programming", "puzzles", "and", "code", "golf" }));
  Console.WriteLine(codeGolf.E(new string[] { "a", "bcd", "efgh", "i", "j" }));
  Console.WriteLine(codeGolf.E(new string[] { "verylongword", "short" }));

p
 r
  o
p  g
 u  r
  z  a
a  z  m
 n  l  m
  d  e  i
c     s  n
 o        g
  d
g  e
 o
  l
   f


a
b
 c
  d
e
 f
  g
i  h
j


v
 e
  r
s  y
 h  l
  o  o
   r  n
    t  g
        w
         o
          r
           d

Pete Arden

Posted 2016-11-13T22:53:06.900

Reputation: 1 151

This appears to output trailing whitespace at the ends of lines, which is not allowed by the challenge specification. Also, requiring strings of spaces to separate the words in the input array is not an allowed input format. – Doorknob – 2016-11-15T01:12:30.160

@Doorknob Oops, sorry... Fixed, only cost me 2 Bytes :) – Pete Arden – 2016-11-15T08:36:17.360

1Compile to a Func<string[], string> and make various other changes for 297 bytes s=>{int i=0,x=0,y=0,r=0,l=s.Length,q=2*(s.Max().Length+l)+1,j;var a=new char[q,q];for(;i<l;i++){y=r;for(j=0;j<s[i].Length;)a[y++,x++]=s[i][j++];x=0;r+=3;}var o="";for(;x<q;x++){var t="";for(y=0;y<q;)t+=a[x,y++];o+=t==string.Join("",Enumerable.Repeat('\0',q))?"":(t.TrimEnd('\0')+"\n");}return o;}; however you need to add 18 bytes for using System.Linq; – TheLethalCoder – 2016-11-15T11:06:36.553

@TheLethalCoder Thanks, but I don't really want to take your entire solution :) – Pete Arden – 2016-11-15T11:49:35.743

It's not mine its yours I just golfed some of the stuff away i.e. moving thwe i and j to the int declaration at the top and moving some of the ++ so they are used on the last use of the variable – TheLethalCoder – 2016-11-15T11:53:14.370

1

Jelly, 24 bytes

z⁶j€⁾  µJ’⁶ẋ;"z⁶œr€⁶Yœr⁷

Try it online!

How?

z⁶j€⁾  µJ’⁶ẋ;"z⁶œr€⁶Yœr⁷ - Main link: a list of strings
z                        - transpose with filler...
 ⁶                       -     space character
  j€                     - join €ach with
    ⁾                    -     two spaces
       µ                 - monadic chain separation, call the result x
        J                - range(length(x)) [1,2,...,x]
         ’               - decrement (vectorises) [0,1,...x-1]
           ẋ             - repeat (vectorises)
          ⁶              - a space ['', ' ',...,'x spaces']
             "           - zip with
            ;            - concatenation (prefixes with the space strings)
              z          - transpose with filler...
               ⁶         -     space character
                œr€⁶     - trim spaces from the right of €ach
                    Y    - join with line feeds
                     œr⁷ - trim line feeds from the right
                         - implicit print

Jonathan Allan

Posted 2016-11-13T22:53:06.900

Reputation: 67 804

1

q/kdb+, 130 109 94 90 86 84 bytes

Solution:

f:{-1(+)a rtrim(til(#)E){raze(x#" "),y,\:"  "}'E:(+)(a:{(max(#:)each x)$x})" "vs x;}

Examples:

q)f "programming puzzles and code golf"
p          
 r         
  o        
p  g       
 u  r      
  z  a     
a  z  m    
 n  l  m   
  d  e  i  
c     s  n 
 o        g
  d        
g  e       
 o         
  l        
   f 
q)f "a bcd efgh i j"
a   


b   
 c  
  d 
e   
 f  
  g 
i  h


j  
q)f (),"x"
x
q)f "verylongword short"
v           
 e          
  r         
s  y        
 h  l       
  o  o      
   r  n     
    t  g    
        w   
         o  
          r 
           d

Explanation (ungolfed):

The basic gist is to create a bunch of equal length strings from the input string, flip (rotate) them, then add appropriate whitespace to get something that looks like this:

"p  p  a  c  g   "
" r  u  n  o  o  "
"  o  z  d  d  l "
"   g  z     e  f"
"    r  l        "
"     a  e       "
"      m  s      "
"       m        "
"        i       "
"         n      "
"          g     "

which is flipped again, and printed to stdout.

Here's a line-by-line breakdown of the concept:

A:"programming puzzles and code golf"; // original input
B:" " vs A;                            // split on " "
C:max count each B;                    // find length of the longest string
D:C$B;                                 // pad each string to this length
E:flip D;                              // flip (rotate) string
F:{raze(x#" "),y,\:"  "};              // appends each char with "  " and prepends an increasing number of " "
G:(til count E)F'E;                    // execute function F with each pair of 0..n and item in list E
H:max count each rtrim G;              // find longest string (ignoring right whitespace)
I:H$G;                                 // pad each of the strings to this length
J:flip I;                              // flip to get result
-1 J;                                  // print to stdout, swallow return value

Notes:

A few ways to shave off some (11) easy bytes if we really wanted to:

  • Could save 2 bytes by dropping the f: and leaving as an anonymous function
  • Could save 3 bytes by dropping the -1 and ; and returning a list of strings rather than printing to stdout
  • Could save 6 bytes if we passed in a list of strings rather than space-separated string

Edits:

  • -11 bytes, use rtrim to find max length to pad, removed need for storing C variable
  • -15 bytes, switching out the max count each for a lambda function a which is created once and used twice
  • -4 bytes, moving the raze into the lambda function to save a raze each
  • -4 bytes, simplified the core lambda function that adds the whitespace
  • -2 bytes, use (+) as shorthand for flip

streetster

Posted 2016-11-13T22:53:06.900

Reputation: 3 635

1

Python 2, 182 bytes

def f(s):
 M=max(map(len,s));p=' '*M;L=[p]+s+M*[p];r='';k=0
 while k/M<len(s)*3+M:
  i=k%M;w=k/M-i+1;r+=(L[(w/3+1)*(w%3==1)]+p)[i];k+=1
  if i==M-1:r=r.rstrip()+'\n'
 return r.strip()

A bit long, but on the positive side, it returns a string with no trailing white space on each line, and no trailing white space or returns at the end; constraints that some other entries don't obey.

A list of words is passed into the function; some 'blanks' are aded to this list and then the algorithm maps a row,column pair to a wordNumber, characterNumber in the expanded list. (This is a bit of the inverse of the usual strategy seen in other solutions).

If we allow trailing white space on all lines except the last, we can do a bit better (163 bytes):

def f(s):
 M=max(map(len,s));p=' '*M;L=[p]+s+M*[p];r='';k=0
 while k/M<len(s)*3+M:i=k%M;w=k/M-i+1;r+=(L[(w/3+1)*(w%3==1)]+p)[i]+'\n'*(i==M-1);k+=1
 return r.strip()

Chas Brown

Posted 2016-11-13T22:53:06.900

Reputation: 8 959

1

Charcoal, 16 9 bytes

WS«P↘ιM³↓

My first Charcoal answer. Thanks to @DLosc for suggestion and instead of using and (Jump) to go back to the start of the line (and three down).

Try it online (verbose) or Try it online (pure).

Explanation:

Loop while there is still a next input-string:

While(InputString()){ ... }
WS« ...

Print this string without moving the cursor in a down-right direction:

Multiprint(:DownRight, i);
P↘ι

And then move three positions down for the next iteration:

Move(3, :Down);
M³↓

Kevin Cruijssen

Posted 2016-11-13T22:53:06.900

Reputation: 67 575

When the challenge needs a single input consisting of an array, Charcoal fails as it splits the input string taking every single word as a separate input. But in Charcoal the θ variable represents the first input, so I just assign the test input to that variable in the header and then write the rest of the code, so you can get rid of the α variable and iterate over the splitted items of θ. Try it online! (Non-competing due to leading spaces.)

– Charlie – 2017-06-30T10:30:39.907

At least, nobody complained when I used that trick here. :-)

– Charlie – 2017-06-30T10:34:34.990

@CarlosAlejo I indeed came across your answer when I was looking for inspiration on existing Charcoal answers. :) – Kevin Cruijssen – 2017-06-30T10:41:27.917

IDK, the method I usually use is just strings + empty string at the end, if any are multiline then input as a python array – ASCII-only – 2017-07-27T02:36:44.160

@CarlosAlejo It's been a while, but I've just used multiple lines now with an empty line to break the while (and golfed 7 bytes at the same time). Saw it being used in one of Neil's answers, and I now see ASCII-only suggested the same thing (somehow missed that comment). – Kevin Cruijssen – 2017-08-14T14:47:28.243

1

Japt -Rx, 17 16 13 bytes

Takes input as an array of words. If trailing whitespace on each line were allowed then the last 4 characters could be removed to tie with the Charcoal solution.

yÈmú3)iYçÃmx1

Try it or run all test cases


Explanation

y                 :Transpose
 È                :Map each word at 0-based index Y
  m               :  Map each character
   ú3             :    Right pad with spaces to length 3
     )            :  End mapping
      i           :  Prepend
       Yç         :   Space repeated Y times
         Ã        :End mapping and transpose
          m       :Map
           x1     :  Trim right
                  :Implicitly join with newlines, trim and output

Shaggy

Posted 2016-11-13T22:53:06.900

Reputation: 24 623

1

K4, 58 bytes

Solution:

+(|/{0+/|\|~^x}@'x)$x:(2-(!c)+3*#x)$"  "/:'$+(c:|/#:'x)$x:

Examples:

q)k)+(|/{0+/|\|~^x}@'x)$x:(2-(!c)+3*#x)$"  "/:'$+(c:|/#:'x)$x:("programming";"puzzles";"and";"code";"golf")
"p          "
" r         "
"  o        "
"p  g       "
" u  r      "
"  z  a     "
"a  z  m    "
" n  l  m   "
"  d  e  i  "
"c     s  n "
" o        g"
"  d        "
"g  e       "
" o         "
"  l        "
"   f       "
q)k)+(|/{0+/|\|~^x}@'x)$x:(2-(!c)+3*#x)$"  "/:'$+(c:|/#:'x)$x:(,"a";"bcd";"efgh";,"i";,"j")
"a   "
"    "
"    "
"b   "
" c  "
"  d "
"e   "
" f  "
"  g "
"i  h"
"    "
"    "
"j   "
q)k)+(|/{0+/|\|~^x}@'x)$x:(2-(!c)+3*#x)$"  "/:'$+(c:|/#:'x)$x:("verylongword";"short")
"v           "
" e          "
"  r         "
"s  y        "
" h  l       "
"  o  o      "
"   r  n     "
"    t  g    "
"        w   "
"         o  "
"          r "
"           d"

Explanation:

Right-pad strings so they are the same length, transpose, join with " ", left-pad to generate diagonals, then right-pad to correct lengths and transpose back. Takes a list of strings and returns a list of strings. Probably golfable but still shorter than my q/kdb+ solution.

+(|/{0+/|\|~^x}@'x)$x:(2-(!c)+3*#x)$"  "/:'$+(c:|/#:'x)$x:
                                                        x:      / save as variable x
                                                       $        / pad
                                             (        )         / do this together
                                                  #:'x          / count (#:) each (') x
                                                |/              / max
                                              c:                / save as variable c
                                            +                   / flip / transpose
                                           $                    / string ($)
                                    "  "/:'                     / join each with "  "
                                   $                            / pad
                      (           )                             / do this together
                                #x                              / count (#) x
                              3*                                / multiply by 3
                             +                                  / add to
                         (  )                                   / do this together
                          !c                                    / range 0..c
                       2-                                       / subtract from 2
                    x:                                          / save as x:
                   $                                            / pad
 (                )                                             / do all this together
    {         }@'x                                              / apply (@) lambda {} to each x
            ^x                                                  / null (^) x (" " is considered null)
           ~                                                    / not
          |                                                     / reverse
        |\                                                      / max (|) scan (\), maxs
     0+/                                                        / sum (+) over (/) starting with 0
  |/                                                            / max (|) over (/), max
+                                                               / transpose

streetster

Posted 2016-11-13T22:53:06.900

Reputation: 3 635

1

Mathematica, 146 bytes

P=PadRight;T=Transpose;R=Riffle;Select[Rest@T@P@MapIndexed[""~Table~#2~Join~#1&,T@P@R[Characters/@#~R~{},{},3]]//.{0->"",{x__,""}->{x}},#!={""}&]&

I'm disappointed by this bytecount, but oh well.

Defines an anonymous function that takes a list of words (e.g. {"this","that","these"}) and returns a two-dimensional array of characters. To view in grid form, add a //Grid at the end.

Converts the strings to an array, adds extra lines, transposes the array, prepends the necessary shifts, then transposes again.

Example result (formatted as grid): Example result

DanTheMan

Posted 2016-11-13T22:53:06.900

Reputation: 3 140

0

Perl 6, 73 bytes

{my@t;for .kv ->\i,\w{for w.comb.kv {@t[3*i+$^a][$^a]=$^b}};@t »||»" "}

Try it online!

The input argument is a list of words. The output is an array of array of characters.

Sean

Posted 2016-11-13T22:53:06.900

Reputation: 4 136

0

PHP, 100 bytes

<?foreach($_GET as$k=>$v)for($x=0;$y=$v[$x];$t[$x++]=$y)($t=&$s[$k*3+$x])?:$t=" ";echo join("
",$s);

Try it online!

Jörg Hülsermann

Posted 2016-11-13T22:53:06.900

Reputation: 13 026