Part of Advent of Code Golf 2021 event. See the linked meta post for details.
The story continues from AoC2017 Day 14.
To recap: The disk is a rectangular grid with \$r\$ rows and \$c\$ columns. Each square in the disk is either free (0) or used (1). So far, you have identified the current status of the disk (a 0-1 matrix), and the number of regions in it (a region is a group of used squares that are all adjacent, not including diagonals).
But we didn't actually defrag the disk yet! Since we identified the regions of used squares, let's assume the shape of each region should be kept intact. It makes it hard to compact the used space, but we can at least move each chunk to the left. Let's do it.
More formally, the algorithm would look like this:
- Identify the regions of used cells in the disk.
- Loop until there is nothing to move:
- Select a region that can be moved 1 unit to the left without overlapping with another region.
- Move it 1 unit to the left. (The regions do not fuse into one even if they become adjacent after such a move.)
Input: A rectangular array of zeroes and ones.
Output: A rectangular array of same size, which represents the result of the simple defrag operation.
For example, if the memory looks like this: (#
is used, .
is free)
##.#.#..
.#.#.#.#
....#.#.
#.#.##.#
.##.#...
##..#..#
.#...#..
##.#.##.
then it has 12 distinct regions
00.1.2..
.0.1.2.3
....4.5.
6.7.44.8
.77.4...
77..4..9
.7...a..
77.b.aa.
which should be defragged in this way:
0012....
.0123...
...45...
6.7448..
.774....
77.49...
.7.a....
77baa...
resulting in the disk state of
####....
.####...
...##...
#.####..
.###....
##.##...
.#.#....
#####...
Standard code-golf rules apply. The shortest code in bytes wins.
Additional test cases
...#####
...#...#
...#.#.#
.....#..
########
->
..#####.
..#...#.
..#..##.
.....#..
########
.....#####..
.....#...#..
.....#.#.#.#
.......#...#
.......#####
->
#####.......
#...#.......
##..##......
.#...#......
.#####......
.....#####../.....#...#../.....#.#.#.#/.......#...#/.......#####
. Requires moving region A one to the left, then B one to the left, A one to the left, ... \$\endgroup\$