with open('test.text', 'r') as file: data: str = file.read().strip() # If block has no ID then it is free class FreeBlock: size: int def __init__(self, s: int): self.size = s def __str__(self) -> str: return '.' * self.size class FileBlock: size: int id: int def __init__(self, size: int, id: int): self.size = size self.id = id def __str__(self) -> str: return str(self.id) * self.size class DiskMap: blocks: list[FreeBlock | FileBlock] def __init__(self, s: str): self.blocks = [] self.parse(s) def parse(self, s: str) -> None: is_file = True id = 0 for char in s: b = FreeBlock(int(char)) if is_file: b = FileBlock(int(char), id) id += 1 is_file = not is_file self.blocks.append(b) # Returns index of first free block or None def findFreeBlock(self) -> int | None: for i, block in enumerate(self.blocks): if type(block) == FreeBlock: return i return None # Returns index of last file block def findLastFile(self) -> int | None: for i, block in reversed(list(enumerate(self.blocks))): if type(block) == FileBlock: return i return None def compact(self) -> None: while True: free_index = self.findFreeBlock() file_index = self.findLastFile() if free_index > file_index: break free_size: int = self.blocks[free_index].size file_size: int = self.blocks[file_index].size file_id: int = self.blocks[file_index].id remaining_file_size = file_size - free_size remaining_free_size = 0 if remaining_file_size < 0: remaining_free_size = abs(remaining_file_size) remaining_file_size = 0 if remaining_free_size != 0: self.blocks[free_index] = FileBlock(free_size - remaining_free_size, file_id) self.blocks.insert(free_index + 1, FreeBlock(remaining_file_size)) self.blocks[file_id] = FreeBlock(free_size) else: self.blocks[free_index] = FileBlock(free_size, file_id) self.blocks[file_index] = FreeBlock(free_size) if remaining_file_size: self.blocks.insert(file_index, FileBlock(remaining_file_size, file_id)) print(free_index) self.print() def print(self) -> None: for block in self.blocks: print(block, end='') print() # Parse Data diskmap = DiskMap(data) diskmap.print() diskmap.compact() diskmap.print()