advent-of-code/2022/7/7.py
2022-12-07 09:48:49 +01:00

109 lines
No EOL
2.4 KiB
Python

"""
parse commandline output, reconstruct a fileststem and determine the sum of all folders < 100kB
"""
text = """$ cd /
$ ls
dir a
14848514 b.txt
8504156 c.dat
dir d
$ cd a
$ ls
dir e
29116 f
2557 g
62596 h.lst
$ cd e
$ ls
584 i
$ cd ..
$ cd ..
$ cd d
$ ls
4060174 j
8033020 d.log
5626152 d.ext
7214296 k
"""
with open('2022/7/stdout.txt') as filein:
text = filein.read()
def parse_stdin(stdin:str):
outputs = stdin.split('$')
outputs = [[l.strip() for l in o.splitlines()] for o in outputs if o]
return recursive_parse(outputs)
def recursive_parse(outputs:list):
structure = {}
while True:
try:
current = outputs.pop(0)
except IndexError:
return structure
command = current.pop(0)
if command.startswith('ls'):
content = [c.split() for c in current]
for value, name in content:
structure[name] = int(value) if value.isnumeric() else value
elif command.startswith('cd'):
dest = command.split()[1]
if dest == '..':
return structure
else:
structure[dest] = recursive_parse(outputs)
def recursive_sum(d:dict, folders:list=None, initial=True):
s=0
folders = [] if folders==None else folders
for name, value in d.items():
if isinstance(value, dict):
zs = recursive_sum(value, folders, False)
folders.append((name,zs))
else:
zs = value
s+=zs
if initial:
return folders
else:
return s
def folders_up_to_size(folders:list, size:int):
return [(k,v) for k,v in folders if v<=size]
def recursive_print(d:dict, indent = 0, increment=2):
for k,v in d.items():
if isinstance( v, dict):
print(' '*indent, 'dir', k)
recursive_print(v, indent+increment)
else:
print(' '*indent, k,v)
system = parse_stdin(text)
# recursive_print(system)
sums = recursive_sum(system)
l = folders_up_to_size(sums,100000)
print(l)
print(sum([v for _,v in l]))
"""
now find the smallest folser that can be deleted to free up the space needed to keep the total size under 40MB
"""
def folders_over_size(folders:list, size:int):
return [(k,v) for k,v in folders if v>size]
total = sums[-1][1]
over = total-40000000
print('filesystem overfull by:', over)
l = folders_over_size(sums,over)
l.sort(key = lambda x: x[1])
print(l[0])