From 3ad90ea8f6bab9220e2bc12a3fefc16395abc5f4 Mon Sep 17 00:00:00 2001 From: An0nSaiko Date: Fri, 9 Dec 2022 14:10:27 +0200 Subject: Day 7 --- day7/solution.nim | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 day7/solution.nim (limited to 'day7/solution.nim') diff --git a/day7/solution.nim b/day7/solution.nim new file mode 100644 index 0000000..e6f4643 --- /dev/null +++ b/day7/solution.nim @@ -0,0 +1,97 @@ +import std/strutils + +type + Command = string + # using LeFile for name because File already exists + LeFile = ref object + Size: int + Name: string + +type + Directory = ref object + Name: string + Files: seq[LeFile] + Parent: Directory + Subdirectories: seq[Directory] + +# Directory methods +method cd(self: Directory, path: string): Directory = + if path == "..": + return self.Parent + + for subdir in self.Subdirectories: + if subdir.Name == path: + return subdir + +method add(self: Directory, file: LeFile): void = + self.Files.add(file) + +method add(self: Directory, dir: Directory): void = + self.Subdirectories.add(dir) + +let total = 70_000_000 +var part1 = 0 +var minRemoved = total + +method size(self: Directory, freeThreshold = total): int = + var size = 0 + for file in self.Files: + size += file.Size + + for subdir in self.Subdirectories: + size += subdir.size(freeThreshold) + + if size <= 100_000: + part1 += size + + if size >= freeThreshold: + minRemoved = min(minRemoved, size) + + return size + +proc run(root: Directory, input: seq[Command]): void = + # start pc from 1 to ignore "cd /" command thats coming first + var pc = 1 + var current = root + + let endpc = input.len() + while pc < endpc: + let command = input[pc] + assert(command[0] == '$') + + let tokens = command.splitWhitespace() + + case tokens[1]: + of "cd": + current = current.cd(tokens[2]) + pc += 1 + of "ls": + pc += 1 + while pc < endpc: + let file = input[pc] + # end of file list + if file[0] == '$': + break + + let fileInfo = file.splitWhitespace() + if fileInfo[0] == "dir": + current.add(Directory(Name: fileInfo[1], Files: @[], Parent: current, Subdirectories: @[])) + else: + current.add(LeFile(Size: fileInfo[0].parseInt(), Name: fileInfo[1])) + pc += 1 + else: + assert(false) + + return + +let content = readFile("./input.txt").strip().splitLines() + +var root = Directory(Name: "/", Files: @[], Parent: nil, Subdirectories: @[]) +run(root, content) + +let totalUsed = root.size() +let totalFree = total - totalUsed +discard root.size(30_000_000 - totalFree) + +echo part1 +echo minRemoved -- cgit v1.2.3