def part1(input_data): output = input_data.split('\n') fs = [] cwd = "" for line in output: line = line.split() if line[0] == '$': # command if line[1] == 'cd': if line[2] == '..': cwd = '/'.join(cwd.split('/')[:-1]) if not cwd: cwd = '/' else: if not cwd: fs.append('/') cwd = line[2] else: cwd += ('/' if not cwd.endswith('/') else '') + line[2] elif line[1] == 'ls': # noop pass else: if line[0] == 'dir': fs.append(cwd + ('/' if not cwd.endswith('/') else '') + line[1]) else: fs.append(cwd + ('/' if not cwd.endswith('/') else '') + line[1] + ',' + line[0]) counts = {x: 0 for x in fs if not ',' in x} for dir in counts.keys(): for f in fs: if f.startswith(dir) and ',' in f: counts[dir] += int(f.split(',')[-1]) maxx = 100000 return sum([y for x, y in counts.items() if y <= maxx]) def part2(input_data): output = input_data.split('\n') fs = [] cwd = "" for line in output: line = line.split() if line[0] == '$': # command if line[1] == 'cd': if line[2] == '..': cwd = '/'.join(cwd.split('/')[:-1]) if not cwd: cwd = '/' else: if not cwd: fs.append('/') cwd = line[2] else: cwd += ('/' if not cwd.endswith('/') else '') + line[2] elif line[1] == 'ls': # noop pass else: if line[0] == 'dir': fs.append(cwd + ('/' if not cwd.endswith('/') else '') + line[1]) else: fs.append(cwd + ('/' if not cwd.endswith('/') else '') + line[1] + ',' + line[0]) counts = {x: 0 for x in fs if not ',' in x} for dir in counts.keys(): for f in fs: if f.startswith(dir) and ',' in f: counts[dir] += int(f.split(',')[-1]) total = 70000000 need = 30000000 candidates = {dir: sz for dir, sz in counts.items() if sz > need - (total - counts['/'])} return candidates[min(candidates, key=candidates.get)] if __name__ == '__main__': with open('./input.txt') as f: inp = f.read().strip() print(part1(inp)) print(part2(inp))