-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day07.kt
110 lines (87 loc) · 2.76 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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package day07
import common.InputRepo
import common.readSessionCookie
import common.solve
import util.selectRecursive
import util.splitIntoPair
fun main(args: Array<String>) {
val day = 7
val input = InputRepo(args.readSessionCookie()).get(day = day)
solve(day, input, ::solveDay07Part1, ::solveDay07Part2)
}
fun solveDay07Part1(input: List<String>): Int {
val root = FileNode("/", null)
executeCommands(root, input)
println(root.toTreeString())
val allNodes = listOf(root).asSequence().selectRecursive { children.asSequence() }
return allNodes.filter { it.isDirectory }
.filter { it.size < 100_000 }
.sumOf { it.size }
}
fun solveDay07Part2(input: List<String>): Int {
val totalDiskSpace = 70_000_000
val minimumFreeDiskSpace = 30_000_000
val root = FileNode("/", null)
executeCommands(root, input)
val freeSpace = totalDiskSpace - root.size
val spaceToFree = minimumFreeDiskSpace - freeSpace
val allNodes = listOf(root).asSequence().selectRecursive { children.asSequence() }
return allNodes.filter { it.isDirectory }
.filter { it.size >= spaceToFree }
.minOf { it.size }
}
fun executeCommand(cmd: String, arg: String, currentDir: FileNode<String>, root: FileNode<String>): FileNode<String> {
when (cmd) {
"cd" -> {
return cd(arg, root, currentDir)
}
"ls" -> {
val (info, name) = arg.splitIntoPair(" ")
if (name.isBlank()) {
return currentDir
}
ls(info, currentDir, name)
}
}
return currentDir
}
private fun ls(info: String, currentDir: FileNode<String>, name: String) {
if (info == "dir") {
currentDir.children.add(FileNode(name, currentDir))
} else {
val file = FileNode(name, currentDir, isDirectory = false)
file.size = info.toInt()
currentDir.children.add(file)
}
}
private fun cd(
arg: String,
root: FileNode<String>,
currentDir: FileNode<String>
): FileNode<String> {
return when (arg) {
"/" -> {
root
}
".." -> {
currentDir.parent!!
}
else -> {
currentDir.moveIntoChildren(arg)
}
}
}
private fun executeCommands(root: FileNode<String>, input: List<String>) {
var currentCommand = ""
var currentDir = root
for (line in input) {
if (line.startsWith("$")) {
currentCommand = line.removePrefix("$").trim()
val (cmd, arg) = currentCommand.splitIntoPair(" ")
currentDir = executeCommand(cmd, arg, currentDir, root)
} else {
val (cmd, _) = currentCommand.splitIntoPair(" ")
currentDir = executeCommand(cmd, line, currentDir, root)
}
}
}