solution.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #!/usr/bin/python3
  2. import sys
  3. import re
  4. # part 1
  5. def print_tree(tree, start='/', level=0):
  6. subdirs, size = tree
  7. indent='\t' * level
  8. print(f'{indent}{start} ({size}):')
  9. for d in subdirs:
  10. print_tree(tree[0][d], f'{d}', level + 1)
  11. def update_dirs(tree, pwd):
  12. current_branch = tree[0]
  13. for d in pwd.lstrip('/').split('/'):
  14. if d not in current_branch:
  15. current_branch[d] = [{}, 0]
  16. current_branch = current_branch[d][0]
  17. def update_sizes(tree, pwd, size):
  18. #print('updating size for pwd', pwd, size)
  19. current_branch = tree
  20. tree[1] += size
  21. for d in pwd.lstrip('/').split('/'):
  22. if d in current_branch[0]:
  23. current_branch = current_branch[0][d]
  24. current_branch[1] += size
  25. def recurse_tree_for_sizes(tree):
  26. total = 0
  27. subdirs, size = tree
  28. total += size if size <= 100000 else 0
  29. for d in subdirs:
  30. total += recurse_tree_for_sizes(tree[0][d])
  31. return total
  32. def recurse_tree_for_deletion(tree, candidates, rootsize):
  33. subdirs, size = tree
  34. if 70000000 - rootsize + size >= 30000000:
  35. candidates.append(size)
  36. for d in subdirs:
  37. recurse_tree_for_deletion(tree[0][d], candidates, rootsize)
  38. def solution():
  39. tree = [{}, 0]
  40. pwd = None
  41. for line in sys.stdin:
  42. l = line.strip()
  43. match = None
  44. if (match := re.match(r'^\$ cd (.*)', l)) is not None:
  45. target = match.groups()[0]
  46. #print(pwd, target)
  47. if target == '/':
  48. pwd = target
  49. elif target == '..':
  50. index = pwd.rfind('/')
  51. pwd = '/' if index == 0 else pwd[:index]
  52. else:
  53. pwd += ('/' if len(pwd) > 1 else '') + target
  54. update_dirs(tree, pwd)
  55. continue
  56. elif re.match(r'^\$ ls', l):
  57. continue
  58. elif (match := re.match(r'^dir (.*)', l)) is not None:
  59. continue
  60. elif (match := re.match(r'^([0-9]+) (.*)', l)) is not None:
  61. size, file = match.groups()
  62. #print('size', size, 'file', file)
  63. update_sizes(tree, pwd, int(size))
  64. continue
  65. else:
  66. continue
  67. #print(tree)
  68. print_tree(tree)
  69. print(f'total sizes come to {recurse_tree_for_sizes(tree)}')
  70. # part 2
  71. candidates = []
  72. recurse_tree_for_deletion(tree, candidates, tree[1])
  73. print(f'total sizes come to {min(candidates)}')
  74. solution()