b.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import os, argparse, re
  2. def solve_task(lines):
  3. e = Explorer()
  4. for line in lines:
  5. e.parse_output(line)
  6. folders = e.get_all_folders()
  7. free_space = 70000000 - e.get_size()
  8. missing_space = 30000000 - free_space
  9. large_enough_folder_sizes = [f.size for f in folders if f.size >= missing_space]
  10. large_enough_folder_sizes.sort()
  11. print(f"Free space: {free_space}")
  12. print(f"Missing space: {missing_space}")
  13. print(f"Smallest folder to delete: {large_enough_folder_sizes[0]}")
  14. class Explorer:
  15. def __init__(self):
  16. self.root_node = FolderNode()
  17. self.current_dir = self.root_node
  18. def parse_output(self, line):
  19. tokens = line.split()
  20. if tokens[0] == "$":
  21. self.parse_cmd(tokens[1:])
  22. elif tokens[0] == "dir":
  23. self.current_dir.add_folder(tokens[1])
  24. else:
  25. self.current_dir.add_file(tokens[1], tokens[0])
  26. def get_size(self):
  27. return self.root_node.size
  28. def parse_cmd(self, tokens):
  29. cmd = tokens[0]
  30. if cmd == "cd":
  31. path = tokens[1]
  32. if path == "..":
  33. self.current_dir = self.current_dir.parent
  34. elif path == "/":
  35. self.current_dir = self.root_node
  36. else:
  37. if path in self.current_dir.children:
  38. # Existing name
  39. self.current_dir = self.current_dir.children[path]
  40. else:
  41. self.current_dir.add_folder(path)
  42. self.current_dir = self.current_dir.children[path]
  43. def get_all_folders(self):
  44. all_folders_found = [self.root_node]
  45. folders_to_traverse = [self.root_node]
  46. while len(folders_to_traverse) > 0:
  47. current_folder = folders_to_traverse.pop()
  48. folders_found = [folder for folder in current_folder.children.values() if isinstance(folder, FolderNode)]
  49. all_folders_found.extend(folders_found)
  50. folders_to_traverse.extend(folders_found)
  51. return all_folders_found
  52. class Node:
  53. def __init__(self, parent):
  54. self.size = 0
  55. if parent:
  56. self.parent = parent
  57. else:
  58. self.parent = self
  59. class FileNode(Node):
  60. def __init__(self, parent, name, size):
  61. super().__init__(parent)
  62. self.parent = parent
  63. self.name = name
  64. self.size = int(size)
  65. class FolderNode(Node):
  66. def __init__(self, parent = None, name = "/"):
  67. super().__init__(parent)
  68. self.children = {}
  69. self.name = name
  70. def add(self, node):
  71. self.children[node.name] = node
  72. self.adjust_size(node.size)
  73. def add_file(self, name, size):
  74. file = FileNode(self, name, size)
  75. self.add(file)
  76. def add_folder(self, name):
  77. folder = FolderNode(self, name)
  78. self.add(folder)
  79. def adjust_size(self, increment):
  80. self.size += increment
  81. if not self.is_root():
  82. self.parent.adjust_size(increment)
  83. def is_root(self):
  84. return self.parent == self
  85. def read_lines(filename):
  86. lines = []
  87. with open(filename) as infile:
  88. for raw_line in infile:
  89. line = raw_line.rstrip()
  90. lines.append(line)
  91. return lines
  92. def parse_arguments():
  93. parser = argparse.ArgumentParser(description="Script that solves the case",epilog="Have a nice day!")
  94. parser.add_argument('filename', nargs='?', default="example.txt", help='Input file')
  95. args = parser.parse_args()
  96. return args
  97. def main():
  98. args = parse_arguments()
  99. lines = read_lines(args.filename)
  100. solve_task(lines)
  101. if __name__ == "__main__":
  102. main()