-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay07.kt
95 lines (78 loc) · 2.55 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
87
88
89
90
91
92
93
94
95
package aoc.years.year2022
import aoc.Day
private const val TOTAL_SPACE = 70000000
private const val REQUIRED_SPACE_FOR_UPDATE = 30000000
@Year2022
class Day07 : Day() {
override fun solvePart1(input: List<String>): Any {
return buildFileSystem(input)
.getAllDirs()
.map { it.calculateSize() }
.filter { it <= 100000 }
.sum()
}
override fun solvePart2(input: List<String>): Any {
val fileSystem = buildFileSystem(input)
val requiredSpace = REQUIRED_SPACE_FOR_UPDATE - (TOTAL_SPACE - fileSystem.calculateSize())
return fileSystem
.getAllDirs()
.map { it.calculateSize() }
.sorted()
.first { it >= requiredSpace }
}
private fun buildFileSystem(input: List<String>): File {
val root = File("/")
var currentDir = root
input
.joinToString("\n")
.split("$")
.map { it.split("\n") }
.drop(1)
.forEach {
when (it[0].trimStart()) {
"cd /" -> currentDir = root
"cd .." -> currentDir = currentDir.parent ?: root
"ls" -> {
it
.drop(1)
.map { file -> file.split(" ") }
.dropLast(1)
.map { (filePrefix, filename) ->
File(filename, currentDir, if (filePrefix == "dir") 0 else filePrefix.toInt())
}
.forEach { file -> currentDir.addFile(file) }
}
// "cd dir"
else -> currentDir = currentDir.getDir(it[0].substringAfter("cd "))
}
}
return root
}
}
private data class File(
val name: String,
val parent: File? = null,
val size: Int = 0,
val files: MutableList<File> = mutableListOf()
) {
fun isDirectory() = files.isNotEmpty()
fun getDir(dir: String): File {
return files.first { it.name == dir }
}
fun addFile(file: File) {
files.add(file)
}
fun calculateSize(): Int {
return if (isDirectory()) files.sumOf { it.calculateSize() } else size
}
fun getAllDirs(): List<File> {
return files
.asSequence()
.filter { it.isDirectory() }
.map { it.getAllDirs() }
.flatten()
.toMutableList()
.plus(this)
.toList()
}
}