/
Day07.kt
86 lines (68 loc) · 2.99 KB
/
Day07.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package com.akikanellis.adventofcode.year2022
object Day07 {
private val CD_REGEX = "\\$ cd (.+)".toRegex()
private val DIR_REGEX = "dir (.+)".toRegex()
private val FILE_REGEX = "([0-9]+) (.+)".toRegex()
fun sumOfAllDirectoriesWithTotalSizeLessThan100000(input: String) = rootDirectory(input)
.allSubdirectories()
.map { it.size() }
.filter { it <= 100_000 }
.sum()
fun sizeOfDirectoryToDelete(input: String): Int {
val rootDirectory = rootDirectory(input)
val unusedSpace = 70_000_000 - rootDirectory.size()
val extraUnusedSpaceNeeded = 30_000_000 - unusedSpace
return rootDirectory.allSubdirectories()
.map { it.size() }
.sortedDescending()
.last { it >= extraUnusedSpaceNeeded }
}
private fun rootDirectory(input: String): Directory {
val rootDirectory = Directory(name = "/")
input
.lines()
.fold(rootDirectory) { currentDirectory, terminalOutputLine ->
if (terminalOutputLine.matches(CD_REGEX)) {
val directoryName = CD_REGEX
.matchEntire(terminalOutputLine)!!
.groupValues[1]
return@fold when (directoryName) {
"/" -> rootDirectory
".." -> currentDirectory.parent!!
else -> currentDirectory.childDirectory(directoryName)
}
} else if (terminalOutputLine.matches(DIR_REGEX)) {
val newDirectoryName = DIR_REGEX
.matchEntire(terminalOutputLine)!!
.groupValues[1]
currentDirectory.addChildDirectory(newDirectoryName)
} else if (terminalOutputLine.matches(FILE_REGEX)) {
val newFile = FILE_REGEX
.matchEntire(terminalOutputLine)!!
.groupValues
.let { File(it[2], it[1].toInt()) }
currentDirectory.addChildFile(newFile)
}
return@fold currentDirectory
}
return rootDirectory
}
data class Directory(
val name: String,
val parent: Directory? = null,
val childDirectories: MutableList<Directory> = mutableListOf(),
val childFiles: MutableList<File> = mutableListOf()
) {
fun childDirectory(name: String) = childDirectories.single { it.name == name }
fun allSubdirectories(): List<Directory> =
childDirectories + childDirectories.flatMap { it.allSubdirectories() }
fun size(): Int = childDirectories.sumOf { it.size() } + childFiles.sumOf { it.size }
fun addChildDirectory(name: String) {
childDirectories += Directory(name = name, parent = this)
}
fun addChildFile(file: File) {
childFiles += file
}
}
data class File(val name: String, val size: Int)
}