g | x | w | all
Bytes Lang Time Link
012K ngn/k240529T150446Zmkst
008Uiua SBCS240528T095542Zchunes
069Perl 5 lF240528T030040ZXcali
000Minecraft240527T160846ZLostXOR
059Arturo240526T190615Zchunes
018Charcoal211002T113842ZNeil
064C clang210919T204544Zceilingc
092C clang210918T122309Zjdt
004Pyth220309T204709Zsinvec
028jq211004T015313ZSara J
039Retina 0.8.2211002T093855ZNeil
215Swift 5.5/Xcode 13.0210929T181803ZRoman Po
004RAD210925T222046ZAdalynn
011MY210925T221423ZAdalynn
054TIBasic210923T034659ZYouserna
002Japt v2.0a0210918T122329ZShaggy
015Pari/GP210922T113808Zalephalp
018Python 3 + NumPy210922T073054Ztsh
142JavaScript210922T045358Zzoplonix
053JavaScript ES6210918T121604ZArnauld
00405AB1E210919T210539ZKevin Cr
034Factor210918T204651Zchunes
041Haskell210918T145131ZWheat Wi
034Python 3210918T114213ZJitse
038Ruby210918T155111ZG B
013MATLAB / Octave210918T150841ZLuis Men
005APL Dyalog Extended210918T130625Zovs
026R210918T122643Zpajonk
004Jelly210918T120451Zemanresu
006Vyxal210918T120014Zemanresu

K (ngn/k), 12 bytes

Solution:

{+{x@<x}'+x}

Try it online!

Explanation:

{+{x@<x}'+x} / the solution
{         x} / function taking implicit x argument
         +   / flip (transpose) input matrix
  {    }'    / apply function to each (') row of the matrix
     <x      / get indices to sort row ascending (<)
   x@        / apply (@) these indices to the row
 +           / flip (transpose) matrix back again

Uiua SBCS, 8 bytes

⍜⍉≡(⊏⍏.)

Try it!

Perl 5 -lF, 69 bytes

$a=0;map$r[$a++]+=$_,@F}{say@$_ for reverse map[map$_-->0|0,@r],1..$.

Try it online!

Minecraft, 0 bytes

This is a bit cheaty, but the question does state you can take input in "all reasonable forms" and a grid of Minecraft blocks seems reasonable enough.

Input is given as a vertical grid of sand and air blocks, with 1 represented by a sand block and 0 represented by an air block.

enter image description here

The output is available in the same format and location a moment after the input is given.

enter image description here

This works, of course, because sand blocks are affected by gravity.

Arturo, 59 bytes

$=>[f:$->m->map size m\0'i->map m'r->r\[i-1]f map f&=>sort]

Try it!

Charcoal, 35 20 18 bytes

WS⊞υι↑Eθ⭆01⁻⭆υ§νκλ

Try it online! Link is to verbose version of code. Takes input as a list of digit strings. Explanation:

WS⊞υι

Read the input.

↑Eθ⭆01⁻⭆υ§νκλ

Map over each column, taking the transpose and removing the 0s and 1s each time, so that the 1s are effectively sorted to the front, but then print the whole lot vertically which rotates the result so that the mapped rows turn back into columns but also the 1s end up at the bottom as desired.

Previous 35-byte canvas-based version:

WS⟦ι⟧↑WKK«WKK«F⁼⪫KD²↓ω10↓01↑»↓WKK↓↗

Try it online! Link is to verbose version of code. Takes input as a list of digit strings although commas can be redundantly included as per the example link. Explanation:

WS⟦ι⟧

Copy the input to the canvas.

Start at the bottom of the first column.

WKK«

Repeat while there are still columns to process.

WKK«

Repeat until this column has been processed.

F⁼⪫KD²↓ω10

If this column contains a 1 above a 0, then...

↓01

... switch the characters, moving down so that the 1 gets considered for gravity again on the next pass.

Try the next digit.

»↓WKK↓↗

Locate the bottom of the next column.

C (clang), 80 79 73 64 bytes

i;f(*a,w,h){for(i=w;i<w*h;)i=a[i-w]>a[i]?a[i-w]---a[i]+++w:i+1;}

Try it online!

This is essentially a strided sort looped over all columns except instead of swapping out of order elements, both elements are xor'ed by one out of order elements are decremented and incremented until they are in order. Thanks to @jdt for the -9!

Slightly less golfed

x,*u;
f(*a,w,h){
  for(x=w*h*--h;x--;)
    w[u=a+x%h*w-x/h/~h]<*u?
      u[w]^=1,
      *u^=1
    :
      0;
}

C (clang), 92 bytes

c,x,y,*p;f(*a,w,h){for(x=0;x<w;x++)for(c=y=0;y<h*2;y++)p=a+x+y%h*w,y<h?c+=*p:(*p=y-h>=h-c);}

Try it online!

Pyth, 4 bytes

CSMC

Try it online!

CSMC

   C  # transpose the matrix
 SM   # sort each row
C     # transpose again

jq, 28 bytes

[transpose[]|sort]|transpose

Try it online!

Retina 0.8.2, 39 bytes

+`(?<=(.)*)1(.*¶(?<-1>.)*(?(1)^))0
0$+1

Try it online! Takes input as a list of digit strings although commas can be redundantly included as per the example link. Explanation: .NET's balancing groups are used to ensure that the regular expression matches a 1 directly above a 0; the digits are thus exchanged. $+ is used instead of $2 due to the following digit which would otherwise be interpreted as part of the substitution name. The + modifier repeats the substitutions until all of the gravity has been applied.

Swift 5.5/Xcode 13.0, 215 bytes

var c=[Int:Int]();let d=m.count;let e=m[0].count;for i in 0..<e{for j in 0..<d{c[i,default:0]+=m[j][i]}};var r=Array(repeating:Array(repeating:1,count:e),count:d);for k in c{for i in 0..<d-k.1{r[i][k.0]=0}};return r

Try it online!

RAD, 4 bytes

⍉<⍉⍵

Try it online!

Transpose the input (⍉⍵), sort each (<), then retranspose .

MY, 11 bytes

⎕⍉86ǵ'ƒ⇹(⍉←

Try it online!

⎕⍉86ǵ'ƒ⇹(⍉←
⎕              - Input
 ⍉             - Transpose
   86ǵ'ƒ⇹(     - Sort each
           ⍉   - Transpose again
             ←  - Output

TI-Basic, 54 bytes

Input [A]
dim([A]
For(I,1,Ans(2
Matr►list([A],I,A
SortA(ʟA
For(J,1,dim(ʟA
ʟA(J→[A](J,I
End
End

Output is stored in [A], which was the inputted matrix.

Japt v2.0a0, 2 bytes

Transposes, sorts each row and automatically transposes back.

yn

Try it

Japt, 3 bytes

Transpose, sort rows, transpose.

yÍy

Try it

Pari/GP, 15 bytes

a->vecsort(a~)~

Try it online!

Python 3 + NumPy, 18 bytes

lambda a:a.sort(0)

Try it online!

Input a np.array, output by modify it in-place.

JavaScript, 142 Bytes

for(j=0,l=a.length,w=a[0].length,c=new Array(l),e=1;j<w;j++){for(i=0;i<l;i++){if(a[i][j]){p=l-e++;!c[p]&&(c[p]=new Array(w));c[p][j]=1}}e=1;}

Where a is the input array and c is the output array.

Might be cheating since I am pulling a vacuum on all the 0s rather then applying gravity to all the 1s.

It works similar to the rest of the solutions where you need to rotate the array and sort it but it does it all in one go and without using any of the built in sort/rotate functions.

JavaScript (ES6), 53 bytes

Suggested by @l4m2: counting the number of 1's on each column, using .filter().

Returns a matrix of Boolean values.

m=>m.map((r,y)=>r.map((_,x)=>!m.filter(r=>!r[x])[y]))

Try it online!


JavaScript (ES6), 55 bytes

Sorting the columns.

m=>m.map((r,y)=>r.map((_,x)=>m.map(r=>r[x]).sort()[y]))

Try it online!


JavaScript (ES6), 57 bytes

Counting the number of 1's on each column, using .some().

Returns a matrix of Boolean values.

m=>m.map((r,y)=>r.map((_,x)=>m.some(r=>!m[n+=r[x]],n=y)))

Try it online!

05AB1E, 4 bytes

ø€{ø

Similar as some of the other answers.

Try it online or verify all test cases.

Explanation:

ø     # Zip/transpose the (implicit) input-matrix, swapping rows/columns
 €{   # Sort each inner list
   ø  # Zip/transpose back
      # (after which the result is output implicitly)

Factor, 34 bytes

[ flip [ natural-sort ] map flip ]

Try it online!

Transpose (flip), sort each row, transpose.

Haskell, 41 bytes

import Data.List
t=transpose
t.map sort.t

Try it online!

This is the same boring answer you've already seen in this thread. Unfortunately it's quite short. Here's a fun answer that doesn't import anything:

No imports, 53 49 bytes

q=foldr.zipWith
e=[]:e
q(:)e.q([(0:),(++[1])]!!)e

Try it online!

This answer is a little odd.

Explanation

Let's first solve an easier problem. Instead of having gravity acting down it will act to the right.

Here each row acts independently so we can just solve it on 1 row and map it across the whole thing. We start by making a function

0#x=0:x
1#x=x++[1]

This takes a list and a value, adds it to the front if it is 0 and the end if it's 1. This will always insert new values to the proper place in the row, so to build the row we can just do:

foldr(#)[]

and to make the complete thing we just add the map

f=map$foldr(#)[]

Ok, now we want to solve the original problem. How can we make this act on the columns? The idea is to use zipWith. zipWith acts independently on the columns of two lists to combine them. So zipWith(#) will take a list of columns and a list of values and add each value to the corresponding column. To do this repeatedly we use foldr

e=[]:e
foldr(zipWith(#))e

The issue however arises that because we are treating the columns as lists the output is transposed. So we need to transpose it back.

If we take a look at the short way to transpose in Haskell here

e=[]:e
foldr(zipWith(:))e

we instantly notice that this is extremely similar to the code we have already written, so we can abstract it. When we do that and add in our transpose we get nearly the final answer

0#x=0:x
1#x=x++[1]
q=foldr.zipWith
e=[]:e
f=q(:)e.q(#)e

The last change is that we can express our original function (#) in pointfree as ([(0:),(++[1])]!!) and substitute it where (#) goes.

q=foldr.zipWith
e=[]:e
f=q(:)e.q([(0:),(++[1])]!!)e

Python 3, 34 bytes

lambda a:zip(*map(sorted,zip(*a)))

Try it online!

-3 bytes thanks to pxeger

Ruby, 38 bytes

->l{l.transpose.map(&:sort).transpose}

Try it online!

MATLAB / Octave, 13 bytes

@(M)sort(M,1)

Try it online!

How it works

Anonymous function that sorts along the 1st dimension, i.e. vertically.

APL (Dyalog Extended), 5 bytes

∧⍤1⍢⍉

Try it online!

Sort each row ⍤1 while transposed ⍢⍉


APL (Dyalog Unicode), 9 bytes

⊖⍳∘≢∘.≤+⌿

Try it online!

+⌿ sum of each column
⍳∘≢ indices from 1 to the number of rows
∘.≤ -table between these two vectors
vertically reverse the resulting matrix

R, 26 bytes

Or R>=4.1, 19 bytes by replacing the word function with \.

function(m)apply(m,2,sort)

Try it online!

Jelly, 4 bytes

ZṢ€Z

Try it online!

A monadic link which takes a 2d array of booleans.

Z    # Transpose
  €  # For each
 Ṣ   # Sort
   Z # Transpose back

Vyxal, 6 bytes

ÞTvsÞT

Try it Online!

There's probably something cleverer / shorter.

ÞT     # Transpose
  vs   # Sort each
    ÞT # Transpose