2022-12-18 03:12:54 +10:30
|
|
|
val fileSizePattern = raw"(\d+) ([\w.]+)".r
|
|
|
|
val cdPattern = "\\$ cd ([\\/\\w.]+)".r // raw string interpolation doesn't like \$
|
|
|
|
val rootPattern = raw"\/(.*)".r
|
|
|
|
|
|
|
|
def cd(cwd: String, to: String): String = to match
|
|
|
|
case rootPattern(absPath) => absPath // Absolute path
|
|
|
|
case ".." =>
|
2022-12-18 03:15:22 +10:30
|
|
|
val i = cwd lastIndexOf '/'
|
2022-12-18 03:12:54 +10:30
|
|
|
if i < 0 then cwd else cwd.substring(0, i) // Up one subfolder
|
|
|
|
case _ => s"$cwd/$to"
|
|
|
|
|
|
|
|
@main def main() =
|
|
|
|
val inputLines = scala.io.Source.fromFile("input/07").getLines
|
|
|
|
|
|
|
|
var cwd = "" // We append the / at time of use
|
|
|
|
val folders = scala.collection.mutable.HashSet[String](cwd)
|
|
|
|
val fileSizes = scala.collection.mutable.HashMap[String, Int]()
|
2022-12-18 03:18:09 +10:30
|
|
|
for line <- inputLines do line match
|
|
|
|
case cdPattern(dir) =>
|
|
|
|
cwd = cd(cwd, dir)
|
|
|
|
folders += cwd
|
|
|
|
case fileSizePattern(sizeStr, filename) =>
|
|
|
|
fileSizes += s"$cwd/$filename" -> sizeStr.toInt
|
|
|
|
case _ => {} // "$ ls", "dir ..."
|
2022-12-18 03:12:54 +10:30
|
|
|
// Very inefficient way of calculating folder sizes, but cute enough
|
|
|
|
val folderSizes = folders.map(f => (f, fileSizes.filter((k,v) => k startsWith s"$f/").values.sum)).toMap
|
|
|
|
|
|
|
|
println(s"Part 1: ${folderSizes.values.filter(v => v <= 100_000).sum}")
|
|
|
|
|
|
|
|
val totalCapacity = 70_000_000
|
|
|
|
val desiredRemaining = 30_000_000
|
|
|
|
val currentRemaining = totalCapacity - folderSizes("")
|
|
|
|
val sizeToDelete = desiredRemaining - currentRemaining
|
|
|
|
println(s"Part 2: ${folderSizes.values.filter(v => v > sizeToDelete).min}")
|