I have a matrix for ex.:
xy 1 2 3 4 5
-------------
1| 1 1 1 2 3
2| 3 0 2 0 0
3| 2 2 1 3 0
4| 3 1 3 2 3
5| 1 0 0 1 0
6| 0 2 1 3 1
-------------
and I want to push all the zeros to the bottom of each column, like this:
xy 1 2 3 4 5
-------------
1| 1 1 1 2 3
2| 3 2 2 3 3
3| 2 1 1 2 1
4| 3 2 3 1 0
5| 1 0 1 3 0
6| 0 0 0 0 0
-------------
I made this procedure but doesn't work properly, sometimes it works on some columns but leaves zeros in the middle on others
procedure MoveZeros(var matnum:matriz);
var x,y,aux:integer;
begin
for y:= min to maxcol do begin
for x:= min to maxfil do begin
if (matnum[x,y] = 0) then begin
matnum[x,y] := matnum[x+1,y];
matnum[x+1,y]:=0;
end;
end;
end;
end;
any ideas?
Your approach will work if you never see more than one 0 at a time - if you do then only the last in the sequence will be moved down.
The trick here is to use a separate pointer that holds the position the highest unfilled zero that we've seen. Then, when we see a non-zero value we move it to this position and increment the pointer. Once we reach the bottom of the column, if this pointer isn't at the end then we write in a 0 and increment the pointer until it is.
Hopefully it won't be too difficult to convert this simple Java code to Pascal
int[][] a = {{1, 1, 1, 2, 3},
{3, 0, 2, 0, 0},
{2, 2, 1, 3, 0},
{3, 1, 3, 2, 3},
{1, 0, 0, 1, 0},
{0, 2, 1, 3, 1},
};
for(int y=0; y<a[0].length; y++)
{
int z = 0;
for(int x=0; x<a.length; x++)
{
if(a[x][y] != 0)
{
if(z < x)
a[z][y] = a[x][y];
z += 1;
}
}
for(; z<a.length; z++)
a[z][y] = 0;
}
for(int[] row : a)
System.out.println(Arrays.toString(row));
Output:
[1, 1, 1, 2, 3]
[3, 2, 2, 3, 3]
[2, 1, 1, 2, 1]
[3, 2, 3, 1, 0]
[1, 0, 1, 3, 0]
[0, 0, 0, 0, 0]