@@ -35,7 +35,10 @@ class Filesystem(var files: MutableList<File>, var gaps: RangeList) {
3535 file.blocks.sortBy(Range ::last)
3636 }
3737
38- fun rearrange () {
38+ /* *
39+ * Reparse before using this.
40+ */
41+ fun rearrange1 () {
3942 // We want to get the highest block and move it to the earliest position if
4043 // it makes sense to do so.
4144 while (true ) {
@@ -103,6 +106,43 @@ class Filesystem(var files: MutableList<File>, var gaps: RangeList) {
103106 }
104107 }
105108
109+ /* *
110+ * Reparse before using this.
111+ */
112+ fun rearrange2 () {
113+ for (file in files.reversed()) {
114+ // At this point, each file only has one range.
115+ val fileId = file.id
116+ val fileRange = file.blocks.lastOrNull() ? : error(" No data for $fileId " )
117+ val fileRangeSize = fileRange.size()
118+
119+ // Find the first gap it will fit.
120+ val gap = gaps.firstOrNull { gap -> gap.size() >= fileRangeSize && gap.start < fileRange.start} ? : continue
121+ val gapSize = gap.size()
122+
123+ when {
124+ fileRangeSize == gapSize -> {
125+ // The files are the same size. Just move the file to the gap.
126+ file.blocks = mutableListOf (gap)
127+ gaps.remove(gap)
128+ }
129+ fileRangeSize < gapSize -> {
130+ val dividingPoint = gap.start + fileRangeSize
131+ val gap1 = gap.start until dividingPoint
132+ val gap2 = dividingPoint.. gap.last
133+
134+ file.blocks = mutableListOf (gap1)
135+ gaps.remove(gap)
136+ gaps.add(gap2)
137+ }
138+ }
139+
140+ // Sort the gaps.
141+ sortGaps()
142+ gaps = mergeRanges(gaps)
143+ }
144+ }
145+
106146 fun mergeRanges (ranges : MutableList <Range >): MutableList <Range > {
107147 if (ranges.isEmpty()) return mutableListOf ()
108148
@@ -162,12 +202,15 @@ class Filesystem(var files: MutableList<File>, var gaps: RangeList) {
162202
163203fun answer1 (input : String ): BigInteger {
164204 val f = Filesystem .parse(input)
165- f.rearrange ()
205+ f.rearrange1 ()
166206 return f.checksum()
167207}
168208
169- fun answer2 (input : String ): Int =
170- TODO ()
209+ fun answer2 (input : String ): BigInteger {
210+ val f = Filesystem .parse(input)
211+ f.rearrange2()
212+ return f.checksum()
213+ }
171214
172215
173216fun main () {
@@ -178,6 +221,6 @@ fun main() {
178221 // Part 1: 6384282079460
179222 println (" Part 1: ${answer1(input)} " )
180223
181- // Part 2:
182- // println("Part 2: ${answer2(input)}")
224+ // Part 2: 6408966547049
225+ println (" Part 2: ${answer2(input)} " )
183226}
0 commit comments