diff --git a/.gitignore b/.gitignore index 3835608..3c5b90b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ **/input.txt +**/example.txt .direnv node_modules \ No newline at end of file diff --git a/day9/part1.kts b/day9/part1.kts new file mode 100644 index 0000000..359dfff --- /dev/null +++ b/day9/part1.kts @@ -0,0 +1,76 @@ +#!/usr/bin/env kotlin + +import java.io.File +import java.util.* +import kotlin.math.min + +data class ReplicatedData( + var fileId: Int?, + var times: Int, +) + +val disk = File(if (args.size >= 1 && args[0] == "example") "./example.txt" else "./input.txt").readLines()[0] + +// Parse into labeled sections +var id = 0 +val parsed = LinkedList(disk.mapIndexed { i, char -> // I love linked lists i love linked lists i love linked lists + val num = char.digitToInt() + + if (i % 2 == 0) { + // Every other starting with i = 0 should be real data + ReplicatedData( + fileId = i / 2, + times = num + ) + } else { + ReplicatedData( + fileId = null, + times = num + ) + } +}.filter { it.times != 0 }) + +val iter = parsed.listIterator() +var blocksFilled = 0 + +while (iter.hasNext()) { + val currentGroup = iter.next() + if (currentGroup.fileId != null || currentGroup.times < 1) continue + + val (groupTakingFromIndex, groupTakingFrom) = parsed.asReversed() + .filter {it.times > 0 } + .withIndex() + .find { (_, it) -> it.fileId != null } ?: break + if (parsed.size - 1 - groupTakingFromIndex <= iter.nextIndex() - 1) break + + val amountToMove = min(currentGroup.times, groupTakingFrom.times) + + // Take the amount we are moving from the previous location + groupTakingFrom.times -= amountToMove + // And add it before the current one + val originalEmptySpace = currentGroup.times + iter.set( + ReplicatedData( + fileId = groupTakingFrom.fileId, + times = amountToMove + ) + ) + blocksFilled += amountToMove + // If we still have some left, insert back in the empty space and rewind the cursor + if (amountToMove < originalEmptySpace) { + iter.add( + ReplicatedData( + fileId = null, + times = originalEmptySpace - amountToMove + ) + ) + iter.previous() // Go back one so the next iteration of the loop will catch the new empty data we just added + } +} + +println( + parsed + .filter { it.times > 0 && it.fileId != null } + .flatMap { group -> (1..group.times).map { _ -> group.fileId!! } } + .mapIndexed { i, data -> i.toULong() * data.toULong() }.sum() +) \ No newline at end of file diff --git a/day9/part2.kts b/day9/part2.kts new file mode 100644 index 0000000..aee16e8 --- /dev/null +++ b/day9/part2.kts @@ -0,0 +1,47 @@ +#!/usr/bin/env kotlin + +import java.io.File +import java.util.* + +val debug = true + +val disk = File(if (args.size >= 1 && args[0] == "example") "./example.txt" else "./input.txt").readLines()[0] + +// Parse into labeled sections +var id = 0 +val parsed = disk.flatMapIndexed { i, char -> // I love linked lists i love linked lists i love linked lists + val num = char.digitToInt() + + if (i % 2 == 0) { + // Every other starting with i = 0 should be real data + List(num) { i / 2 } + } else { + List(num) { null } + } +}.toMutableList() + +var iter = parsed.asReversed().listIterator() +println(parsed.asReversed()) +while (true) { + var startOfGroup = iter.next() + while (startOfGroup == null) { + startOfGroup = iter.next() + } + println(iter.nextIndex() - 1) + var endOfGroup = iter.next() + while (endOfGroup == startOfGroup) { + endOfGroup = iter.next() + } + iter.previous() + println(iter.nextIndex() - 1) + break + + + var emptySpaceBuffer = 0 + for (i in parsed.indices) { + if (parsed[i] == null) emptySpaceBuffer += 1 + else emptySpaceBuffer = 0 + +// if (emptySpaceBuffer == ) + } +} \ No newline at end of file