AdventOfCode/2022/day07.scala

35 lines
1.4 KiB
Scala

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 ".." =>
val i = cwd lastIndexOf '/'
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]()
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 ..."
// 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}")