AoC/2022/day7.swift
2022-12-07 20:57:34 +01:00

93 lines
2.1 KiB
Swift

import Foundation
class Directory {
var parent: Directory? = nil
var children: [String: Directory] = [:]
var size: Int = 0
init(parent: Directory? = nil) {
self.parent = parent
}
func child(_ name: String) -> Directory {
if let child = children[name] {
return child
}
let new = Directory(parent: self)
children[name] = new
return new
}
func totalSize() -> Int {
return size + children.values.reduce(0) { $0 + $1.totalSize() }
}
func all(_ callback: (Directory) -> Void) {
callback(self)
for child in children.values {
child.all(callback)
}
}
}
let input = try String(contentsOf: URL(fileURLWithPath: "day7.input"))
let scanner = Scanner(string: input)
let root = Directory()
var current: Directory? = nil
while !scanner.isAtEnd {
guard scanner.scanString("$") != nil else {
fatalError("Expected $")
}
if scanner.scanString("cd") != nil, let dir = scanner.scanUpToString("\n") {
switch dir {
case "/":
current = root
case "..":
current = current!.parent
default:
current = current!.child(dir)
}
} else if scanner.scanString("ls") != nil {
while true {
if let size = scanner.scanInt() {
current!.size += size
} else if scanner.scanString("dir") != nil {
} else {
break
}
_ = scanner.scanUpToString("\n");
}
}
}
var sum = 0
root.all {
let size = $0.totalSize()
if size < 100000 {
sum += size
}
}
print("Part 1: Sum of size of all directories < 100000:", sum)
let diskSize = 70000000
let freeSpace = diskSize - root.totalSize()
let requiredSize = 30000000
let toFree = requiredSize - freeSpace
var smallest = Int.max
root.all {
let size = $0.totalSize()
if size >= toFree && size < smallest {
smallest = size
}
}
print("Part 2: Smallest folder to delete:", smallest)