| Problem statement | Source code | Tags: Data structures
This problem pays tribute to 2021 day 23.
The first step is to parse the input into the same format as used in the demonstration: an array of blocks, which is -1 if empty, and the file ID otherwise.
Then we make a list of blank positions, which we can use for insertion later.
Now we can loop through each block position from the end, using the list of blank positions as a queue. Each time we find a non-empty blank, we swap it with the first blank position in the list, and remove that position from the list. We stop when the iteration reaches the start of the blocks array, or when the current block is to the left of the first blank position.
Finally calculate the checksum as specified:
Now we want to move files as a whole, meaning we can no longer iterate blocks as discrete things. So the first step is to represent the disk as segments. My representation of the disk is a list of segments, where each segment contains a list of files followed by a free space:
Now I iterate through the segments from the end, and for each segment, I try to move each file in it to the leftmost segment that has enough free space.
Each time, I try to empty a segment by moving all of its files to the left. I go through each file, right to left (which is head to tail in the files list), and search for the leftmost segment with enough free space (s.free_size >= occ). Noticing that for each segment, files are always removed from the right and added to the right, I store the files in reverse order, so that the last file is always at the head of the list. If a suitable pos is found, I need to update the following:
ind of the file to be the new position in the target segment.free_size of the target segment by the size of the file.files list (which is the head of the list).files list. I have a remaining_files list that I build up, which are the files that I can't move and should remain in the current segment.free_size, which is only relevant for segments waiting to receive files. This also means that I don't have to merge any fragmented space either.Because each file knows its index, the checksum is as straightforward as part 1.