1
+ package com.advent.d7
2
+
3
+ import com.advent.d7.Day7.Operation
4
+ import com.advent.d7.Day7.toOperation
5
+ import com.advent.readLinesFromFile
6
+ import java.util.*
7
+
8
+ /* *
9
+ * @author Mateusz Becker
10
+ */
11
+ fun main () {
12
+
13
+ // val input = Day7.exampleData()
14
+ val input = readLinesFromFile(" input_d7.txt" )
15
+
16
+ data class File (val fileName : String , val size : Long )
17
+ data class Dir (
18
+ val name : String ,
19
+ val parent : Dir ? ,
20
+ val directories : MutableList <Dir >,
21
+ val files : MutableList <File >,
22
+ var size : Long
23
+ ) {
24
+ override fun toString (): String {
25
+ return " DIR: ${name} , ${size} , ${files} "
26
+ // return "DIR: ${name}, ${size}, ${files},\n $directories"
27
+ }
28
+ }
29
+
30
+ fun scanLinesForDirsAndFiles (): Dir {
31
+ var operation: Operation = Operation .CD
32
+
33
+ var currentDir = Dir (" /" , null , mutableListOf (), mutableListOf (), 0 )
34
+ val rootDir = currentDir
35
+
36
+ for (line in input) {
37
+ val content = line.split(" " )
38
+ if (content[0 ] == " ${' $' } " ) {
39
+ operation = content[1 ].toOperation()
40
+ }
41
+ when (operation) {
42
+ Operation .CD -> {
43
+ val name = content[2 ]
44
+ if (name == " .." ) {
45
+ currentDir = currentDir.parent!!
46
+ } else {
47
+ if (name != " /" ) {
48
+ currentDir = Dir (name, currentDir, mutableListOf (), mutableListOf (), 0 )
49
+ currentDir.parent!! .directories + = currentDir
50
+ }
51
+ }
52
+ }
53
+ Operation .LS -> {
54
+ content[0 ].toLongOrNull()?.let { size ->
55
+ currentDir.files + = File (content[1 ], size)
56
+ }
57
+ }
58
+ }
59
+ }
60
+ return rootDir
61
+ }
62
+
63
+ val dirs = PriorityQueue <Dir >(Comparator .comparing { dir -> dir.size })
64
+
65
+ fun computeSizeInDirsRecursive (currentDir : Dir ) {
66
+ for (dir in currentDir.directories) {
67
+ computeSizeInDirsRecursive(dir)
68
+ }
69
+ val filesSize = currentDir.files.fold(0L ) { acc, file -> file.size + acc }
70
+ val dirsSize = currentDir.directories.fold(0L ) { acc, dir -> dir.size + acc }
71
+ currentDir.size = dirsSize + filesSize
72
+
73
+ dirs + = currentDir
74
+ }
75
+
76
+ val rootDir = scanLinesForDirsAndFiles()
77
+ computeSizeInDirsRecursive(rootDir)
78
+ val dirs2 = PriorityQueue (dirs)
79
+
80
+ fun part1Answer (dirs : Queue <Dir >): Long {
81
+ var size: Long = 0
82
+ var acc: Long = 0
83
+ while (dirs.isNotEmpty()) {
84
+ size = dirs.poll().size
85
+ if (size > 100_000 ) {
86
+ break
87
+ }
88
+ acc + = size
89
+ }
90
+ return acc
91
+ }
92
+
93
+ val answer = part1Answer(dirs)
94
+ println (" Day7 part 1 answer: $answer " )
95
+
96
+ val diskSpace: Long = 70000000
97
+ val minDiscSpace: Long = 30000000
98
+ val toDelete = minDiscSpace - (diskSpace - rootDir.size)
99
+
100
+ fun part2Answer (dirs : Queue <Dir >): Long {
101
+ var size: Long
102
+ do {
103
+ size = dirs.poll().size
104
+ } while (size < toDelete)
105
+
106
+ return size
107
+ }
108
+
109
+ val answer2 = part2Answer(dirs2)
110
+ println (" Day7 part 2 answer: $answer2 " )
111
+
112
+ }
113
+
114
+
115
+ object Day7 {
116
+ fun exampleData () = """
117
+ ${' $' } cd /
118
+ ${' $' } ls
119
+ dir a
120
+ 14848514 b.txt
121
+ 8504156 c.dat
122
+ dir d
123
+ ${' $' } cd a
124
+ ${' $' } ls
125
+ dir e
126
+ 29116 f
127
+ 2557 g
128
+ 62596 h.lst
129
+ ${' $' } cd e
130
+ ${' $' } ls
131
+ 584 i
132
+ ${' $' } cd ..
133
+ ${' $' } cd ..
134
+ ${' $' } cd d
135
+ ${' $' } ls
136
+ 4060174 j
137
+ 8033020 d.log
138
+ 5626152 d.ext
139
+ 7214296 k
140
+ """ .trimIndent()
141
+ .split(" \n " )
142
+
143
+ fun String.toOperation (): Operation {
144
+ return Operation .values().find { it.name.lowercase() == this }!!
145
+ }
146
+
147
+ enum class Operation {
148
+ LS , CD
149
+ }
150
+
151
+ }
0 commit comments