a.py 3.5 KB

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