day07 solution

This commit is contained in:
RussellChamp committed 2022-12-08 10:09:26 -05:00
1 parent 90aad38e16
commit 6107f01523
4 files changed
+159 -1

No files matched your search

+75
View File
@@ -0,0 +1,75 @@
class PathNode:
def __init__(self, name, size = 0):
self.name = name
self.size = size
self.parent = None
self.children = {}
def has_parent(self):
# print('%s has a parent? %s' % (self.name, self.parent is not None))
return self.parent is not None
def set_parent(self, parent):
self.parent = parent
def has_child(self, name):
# print('%s has child %s? %s' % (self.name, name, self.children.has_key(name)))
return self.children.has_key(name)
def add_child(self, name, size = 0):
# print('+ adding %s to %s' % (name, self.name))
self.children[name] = PathNode(name, size)
self.children[name].set_parent(self)
self.size += size
ptr = self
while ptr.has_parent():
ptr = ptr.parent
ptr.size += size
def is_directory(self):
return len(self.children) > 0
def print_self(self, indentation = 0):
size = '(%d)' % (self.size) + (' [%d items]' % (len(self.children)) if self.is_directory() else '')
print('%s%s %s' % (' ' * indentation, self.name, size))
for key in self.children:
self.children[key].print_self(indentation+1)
def go_up_one_level(self):
if self.has_parent():
# print('-> moved up one level from %s to %s' % (self.name, self.parent.name))
return self.parent
return self
def go_to_root(self):
if self.has_parent():
# print('-> going to root from %s' % (self.name))
return self.parent.go_to_root()
return self
def go_to_child(self, name):
if self.has_child(name):
# print('-> going to %s from %s' % (name, self.name))
return self.children[name]
return self
def get_directories_le(self, size):
dirs = []
for key in filter(lambda c: self.children[c].is_directory(), self.children):
if self.children[key].size <= size:
dirs.append([self.children[key].name, self.children[key].size])
dirs += self.children[key].get_directories_le(size)
return dirs
def iterate_all_directories(self):
dirs = [[self.name, self.size]]
for key in self.children:
dirs += self.children[key].iterate_all_directories()
return dirs
def find_smallest_at_least(self, required_size):
all_dirs = self.iterate_all_directories()
adequate_size_dirst = filter(lambda item: item[1] >= required_size, all_dirs)
smallest_dir = min(adequate_size_dirst, key=lambda item: item[1])
return smallest_dir
+68
View File
@@ -0,0 +1,68 @@
# Day 07: No Space Left On Device
import os
from PathNode import PathNode
def get_path():
return os.path.join(os.path.dirname(__file__), 'data.txt')
def get_dir_tree():
ptr = PathNode('/')
with open(get_path()) as fp:
for cmd in fp:
cmd = cmd.strip()
# print(cmd)
if cmd[0] == '$':
# commands
if cmd[2:4] == 'ls':
pass # basically a noop
elif cmd[2:4] == 'cd':
if cmd[5:] == '/':
ptr = ptr.go_to_root()
elif cmd[5:] == '..':
ptr = ptr.go_up_one_level()
else:
ptr = ptr.go_to_child(cmd[5:])
pass
elif cmd[:3] == 'dir':
# list a directory
ptr.add_child(cmd[4:])
else:
# listing a file
[size, name] = cmd.split()
ptr.add_child(name, int(size))
return ptr.go_to_root()
def solve_part1():
root = get_dir_tree()
# ptr.print_self()
dirs = root.get_directories_le(100000)
total_size = sum(map(lambda item: item[1], dirs))
print('Day 07: Part 1')
print('GOAL: Find all of the directories with a total size of at most 100000.')
print('ANSWER: What is the sum of the total sizes of those directories?')
print('Total size: %d' % (total_size))
def solve_part2():
total_size = 70000000
required_space = 30000000
root = get_dir_tree()
delete_size = required_space - (total_size - root.size)
# print('Current usage is %d / %d [additional %d needed to get to %d / %d]' % \
# (root.size, total_size, delete_size, total_size - required_space, total_size))
smallest = root.find_smallest_at_least(delete_size)
print('Day 07: Part 2')
print('GOAL: Find the smallest directory that, if deleted, would free up enough space on the filesystem to run the update.')
print('ANSWER: What is the total size of that directory?')
print('Need to free up %d' % delete_size)
print('Smallest directory: %s - %d' % (smallest[0], smallest[1]))
if __name__ == '__main__':
solve_part1()
solve_part2()
+12
View File
@@ -0,0 +1,12 @@
import unittest
class Day07TestMethods(unittest.TestCase):
def setUp(self):
pass
# Does a thing
def test_true(self):
self.assertEqual(True, False)
if __name__ == '__main__':
unittest.main()
+4 -1
View File
@@ -12,12 +12,15 @@ def solve_part1():
for line in fp:
print(line)
print('Day #DAY#: Part 1')
print('GOAL: #GOAL1#')
print('ANSWER: #ANSWER1#')
print('Total: %d' % (total))
def solve_part2():
total = 0
print('Day #DAY#: Part 2')
print('GOAL: #GOAL2#')
print('ANSWER: #ANSWER2#')
print('Total: %d' % (total))