Vertically collapse text
Pyth, 10 bytes
jb_.T.T_.z
Try it online in the Pyth Compiler/Executor.
Idea
We can achieve the desired output by applying four simple transformations:
Reverse the order of the lines:
Golf Code & Puzzles Programming
Transpose rows and columns:
GC&PP oour ldzo fezg lr ea sm m i n g
This top justifies, collapsing the original columns.
Transpose rows and columns:
Golflesming Coderam &uzz Prog P
Reverse the order of the lines:
P Prog &uzz Coderam Golflesming
Code
.z Read the input as a list of strings, delimited by linefeeds.
_ Reverse the list.
.T.T Transpose the list twice.
_ Reverse the list.
jb Join its strings; separate with linefeeds.
Haskell, 62 bytes
import Data.List
p=reverse;o=transpose
f=unlines.p.o.o.p.lines
I'm very mature.
Python 2, 104 bytes
l=[]
for x in input().split('\n'):n=len(x);l=[a[:n]+b[n:]for a,b in zip(l+[x],['']+l)]
print'\n'.join(l)
An iterative one-pass algorithm. We go through each line in order, updating the list l
of lines to output. The new word effectively pushes from the bottom, shifting all letters above it one space. For example, in the test case
Programming
Puzzles
&
Code
Golf
after we've done up to Code
, we have
P
Prog
&uzzram
Codelesming
and then adding Golf
results in
P
Prog
&uzz
Coderam
Golflesming
which we can view as the combination of two pieces
P |
Prog |
&uzz |
Code | ram
Golf | lesming
where the first piece got shifted up by golf
. We perform this shifting with a zip
of the output list with the element at the end (left side) and output list precedence by a blank line (right side), cutting off each part at the length of the new element.
It might seem more natural to instead iterate backwards, letting new letters fall from the top, but my attempt at that turned out longer.
For comparison, here's a zip
/filter
approach, with map(None,*x)
used for iziplongest
(109 bytes):
f=lambda z:[''.join(filter(None,x))for x in map(None,*z)]
lambda x:'\n'.join(f(f(x.split('\n')[::-1]))[::-1])