g | x | w | all
Bytes Lang Time Link
166AWK241202T162918Zxrs
003Vyxal aj241129T205932Zemanresu
055Perl 5 lF240529T180406ZXcali
009Pip rl210602T153952ZDLosc
012Uiua 0.11.0240529T135159ZRomanPro
105Nibbles240526T213934ZDLosc
023Charcoal210602T185243ZNeil
047Wolfram Language Mathematica210605T145019ZLegionMa
180C gcc210602T165003ZNoodle9
108Red210603T193829ZKirill L
011APL Dyalog Unicode210602T145935Zovs
005Husk210603T051616ZRazetime
055Vim210603T040832ZDLosc
076JavaScript ES10note210603T030751Ztsh
068Python 3210602T220401Zhyperneu
046Retina 0.8.2210602T184324ZNeil
006Japt210602T152816ZShaggy
082JavaScript ES10210602T173731ZArnauld
007Vyxal aj210602T172129Za stone
014K ngn/k210602T163414Zcoltim
071Scala 2.12210602T152034Zuser
062Factor + combinators.extras210602T154010Zchunes
005Jelly210602T142238Zhyperneu
00605AB1E210602T152017Zovs
007MATL210602T144611ZLuis Men
014J210602T151411ZJonah

AWK, 166 bytes

Nearly half the code is the print block.

{l=split($0,a[++x],X);for(i=0;i++<l;)for(k=x;k--;)if(a[k][i]~" "){a[k][i]=a[k+1][i];a[k+1][i]=" "}}END{for(;j++<x;print"")for(k=0;k++<l;)printf a[j][k]~" "?X:a[j][k]}

Attempt This Online!

{l=split($0,a[++x],X); # each line is converted to an array
for(i=0;i++<l;)        # for each char
for(k=x;k--;)          # starting at last line
if(a[k][i]~" ")        # if we have a space
{a[k][i]=a[k+1][i];    # copy the character below
a[k+1][i]=" "}}        # char below is now a space

# print block
END{for(;j++<x;print"")for(k=0;k++<l;)printf a[j][k]~" "?X:a[j][k]}

Vyxal aj, 3 bytes

∩ȧ∩

Try it Online!

I/O as lists of lines - the a/j flags format these as newline-separated lines.

∩   # Transpose, getting columns of original input
 ȧ  # Remove whitespace from each column again
  ∩ # Transpose again, without padding, removing empty spaces

Perl 5 -lF, 55 bytes

$i=0;map{$;[$i++].=$_ x!/ /}@F}{say map{s/.//;$&}@;for@

Try it online!

Pip -rl, 11 9 bytes

ZD J*||Zg

Takes input as lines of stdin, padded to a full rectangle. Attempt This Online!

Explanation

           g is list of lines of stdin (-r flag)
       Zg  Zip g (transposing into a list of lists of characters)
     ||    Strip whitespace from each character (replacing spaces with empty string)
   J*      Join each sublist into a single string
ZD         Zip again, padding shorter sublists with empty string
           Autoprint with each sublist on a separate line (-l flag)

Changing the flags to -rP shows the actual structure of the list that gets output:

["a";"f";"b";"g";"c";"g";"d";"h";"l";"e"]
["f";"j";"j";"";"g";"k";"";"l";"";"i"]
["";"";"";"";"k";"";"";"";"";"l"]

Since the -l flag joins each sublist together without a separator, -rl gives us exactly the output we want:

afbgcgdhle
fjjgkli
kl

Uiua 0.11.0, 12 bytes

⍥(≡⊕⊂=@ .⍉)2

Try it out!

Explanation

⍥(≡⊕⊂=@ .⍉)2
⍥(        )2 # Repeat twice (first for columns, then for rows)
         ⍉   # Transpose the array
     =@ .    # Copy the array and mark all spaces
  ≡          # For every "row":
   ⊕⊂        # group by indices (0 = not a space, 1 = space)
             #   and join the groups together

Nibbles, 10 nibbles (5 bytes)

`'.`';@|$$

Attempt This Online!

Explanation

It turns out that Nibbles' builtins are a very good fit for this challenge.

`'.`';@|$$
     ;@     # Read all of stdin as a list of lines
   `'       # Transpose
  .         # Map to each line:
       |$$  #   Filter, keeping truthy characters
            #   In Nibbles, whitespace characters are falsey and other characters are truthy
`'          # Transpose again
            # When there are gaps in the array to be transposed, Nibbles shifts the values
            # over to fill them, so a further whitespace-removal step isn't needed

Charcoal, 26 25 23 bytes

WS⊞υιF²≔E⌊υ◨⁻⭆υ§μλ Lυυυ

Try it online! Link is to verbose version of code. Takes input as newline-terminated space-padded list of strings. Explanation:

WS⊞υι

Input the strings.

F²

Repeat twice.

≔E⌊υ◨⁻⭆υ§μλ Lυυ

Transpose the array, remove the spaces, then right-pad back to the original length.

υ

Output the final result.

Wolfram Language (Mathematica), 47 bytes

a=PadRight[#/." "->Nothing]/. 0->" "&;a@a@#&

Try it online! Pure function. Takes a space-padded matrix of characters and returns the squashed matrix. This function uses the relatively straightforward algorithm: transpose, remove spaces, pad with spaces, and repeat once more. The Unicode character is U+F3C7 for \[Transpose]. Note that without the space, the ReplaceAll expression would be parsed as / .0 -> " ".

C (gcc), 197 \$\cdots\$ 181 180 bytes

Saved a byte thanks to a stone arachnid!!!
Saved 4 bytes thanks to ceilingcat!!!

#define F for(i=0;i<l;)for(j=0,p=t[i++];*p;++p,++j)if(*p<33)for(k
i;j;k;f(t,l,p,q)char**t,*p,*q;{F=i;q=t[k]+j,k<l;)k+=*q-32?*p=*q,*q=32,l:1;F=0,q=p;!k**++q;)*q-32?*p=*q,k=*q=32:0;}

Try it online!

Red, 108 bytes

func[x][loop 2[x: collect[while[x/1/1][keep pad trim/all form collect[forall x[keep take x/1]]length? x]]]x]

Try it online!

Takes input and returns output as a series of strings space-padded to equal length.

APL (Dyalog Unicode), 11 bytes

~∘' '⍤1∘⍉⍣2

Try it online!

A train taking and returning a character matrix.

         ⍣2  ⍝ repeat 2 times:
        ⍉    ⍝ transpose the character matrix
~∘' '        ⍝ remove spaces
     ⍤1      ⍝ in each row
             ⍝ each row is padded with spaces to keep the matrix shape

APL (Dyalog Extended), 8 bytes

-2 bytes thanks to Bubbler!

In the extended variant provides easy access to the dfns namespace, which has a function to drop all blanks.

⌂dab∘⍉⍣2

Try it online!

Husk, 5 bytes

TmfIT

Try it online!

same as jelly

Vim, 55 bytes

YP:s/./\\_./g
Dddqq:%s/\v (<C-r>-)(\S)/\2\1 
@qq@q:%s/ //g

Requires input to be padded to a rectangle. Try it online!

Strategy

We're going to handle the vertical swaps by constructing a regex that will match any \$n\$ characters--including newline--where \$n\$ is the length of each line. Then we look for a space followed by \$n\$ characters followed by a non-space and swap the space for the non-space. Since the potential matches of this regex are overlapping, we'll use a macro to keep on doing the replacement until there are no more matches. Then the horizontal squashing is easy: just remove all spaces.

Explanation

YP

Copy the top line upward. We're going to turn this copy into the regex we need.

:s/./\\_./g<cr>

Replace each character on the line with \_.. In Vim regex, this is a construct that matches any single character including newline (TIL). Line 1 now contains a regex that matches \$n\$ characters.

Ddd

Delete to the end of the line (putting the regex in register -) and then delete the now-blank line (doesn't overwrite - because it's a multiline deletion).

qq

Begin recording macro q:

:%s/\v (<C-r>-)(\S)/\2\1 <cr>

Do a substitution on all lines: space, followed by the regex we stored in register - (group 1), followed by a non-space character (group 2) => group 2, followed by group 1, followed by space. (The \v sequence means we don't have to backslash the parentheses, saving a net 2 bytes.)

@qq

After the substitution, call the macro recursively. Stop recording...

@q

... and call the macro. This recursive macro will run until no more substitutions can be made.

:%s/ //g<cr>

Replace all spaces on all lines with empty string.

JavaScript (ES10note), 76 bytes

a=>(g=a=>a[0].map((c,i)=>a.map(l=>l[i]).sort((x,y)=>(y>' ')-(x>' '))))(g(a))

Try it online!

Just noticed that this Python answer by hyper-neutrino used the same algorithm. You may upvote that one.

Python 3, 68 bytes

lambda x,g=lambda x:[sorted(r,key=' '.find)for r in zip(*x)]:g(g(x))

Try it online!

-15 bytes thanks to dingledooper

Retina 0.8.2, 46 bytes

+`(?<=(.)*) (.*¶(?<-1>.)*(?(1)$))(\S)
$3$2 
 

Try it online! Takes space-padded input. Note: Lines 2 and 3 end in a space. Explanation:

(?<=(.)*) (.*¶(?<-1>.)*(?(1)$))(\S)
$3$2 

Find a space above non-whitespace and exchange the two.

+`

Repeat until no more exchanges can be made.

 

Delete the remaining spaces.

Japt, 6 bytes

Õ¸¬Õ¸¬

Try it

Õ¸¬Õ¸¬     :Implicit input of string
Õ          :Transpose
 ¸         :Split on spaces
  ¬        :Join
   Õ¸¬     :Repeat

Japt -h, 6 bytes

2Æ=Õ¸¬

Try it

2Æ=Õ¸¬     :Implicit input of string U
2Æ         :Map the range [0,2)
  =        :  Reassign to U
   Õ       :  Transpose
    ¸      :  Split U on spaces
     ¬     :  Join
           :Implicit output of last element

JavaScript (ES10), 82 bytes

Expects a space-padded matrix of characters. Returns a list of lists of characters.

m=>m.map(r=>r.flatMap((_,x)=>m.some((r,y)=>1/(c=r[x])||m[y+=[,x]]?0:m[y]=1)?c:[]))

Try it online!

Vyxal aj, 7 bytes

2(ÞTȧvṅ

Try it Online! (Test cases!)

2(ÞTȧvṅ    
2(         Repeat twice:
  ÞT        Transpose
    ȧ       Remove whitespace
     vṅ     Join sublists on empty string

K (ngn/k), 14 bytes

2{{x@<^x}'+x}/

Try it online!

Scala 2.12, 71 bytes

Fixed a mistake thanks to @ophact

1.to(2)./:(_){_.transpose.map{r=>val(x,s)=r.partition(32<);x++s}->_ _1}

Try it in Scastie!

Takes a matrix of characters as input. The non-space characters have to be greater than 32 (ASCII).

1.to(2)  //Make the range[1..2]. This is just to repeat the function twice
./:(_){  //Fold over it with the input as the initial value for the accumulator
_.transpose  //Transpose the matrix first so we can work on the columns
 .map{r=>    //For every row,
  val(x,s)=r.partition(32<); //x is non-space characters, s is spaces
  x++s       //Join those together, with all the spaces at the end
 }->_   //Make a 2-tuple with the current number (either 1 or 2)
 _1}    //Get the first element of that tuple (the matrix), discarding the number

Factor + combinators.extras, 62 bytes

[ [ flip [ [ 32 = ] partition prepend ] map ] twice "\n"join ]

Try it online!

It's a quotation that accepts a matrix of characters/list of strings from the data stack as input and leaves a string on the data stack as output.

Jelly, 5 bytes

Zḟ€⁶Z

Try it online!

Zḟ€⁶Z  Main Link
Z      Transpose the matrix
 ḟ     Filter out
  €    From each row
   ⁶   Spaces
    Z  Transpose the matrix

05AB1E, 6 bytes

Input and output is a list of lists of characters.

2FζðδK

Try it online! or Try all cases!

2F iterate two times:
ζ tranpose the list of lists, padding shorter lists with spaces
ðδK remove all spaces

MATL, 7 bytes

,c!Z{Xz

Try it online! Or verify all test cases.

Input is a char matrix (rectangular char array).

Explanation

,      % Do twice
  c    %   Convert to char. The first time this takes the input (implicit),
       %   and does nothing because the input is already a char matrix. The second
       %   time this transforms the cell array of char vectors at the top of the
       %   stack into a char matrix, right-padding each line with space
  !    %   Transpose
  Z{   %   Convert char matrix into cell array of its rows
  Xz   %   Remove space from each char vector contained in that cell array
       % End (implicit)
       % Display (implicit)

J, 14 bytes

-.&' '"1@|:^:2

Try it online!

Not surprising, but what I came up with is almost identical to ovs's APL approach.

how

Transpose |: and remove spaces -.&' ' on each line "1 two times ^:2.