Last active
December 13, 2022 22:50
-
-
Save DDihanov/3990147076fdc99722ee2496cce40e5b to your computer and use it in GitHub Desktop.
AOC day 13 2022
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.File | |
val input = File("src/main/kotlin/day13/Day13.txt").readLines().mapNotNull { | |
when (it) { | |
"" -> null | |
else -> it | |
} | |
} | |
sealed class Data { | |
data class Integer(val value: Int) : Data() | |
data class ListData(val data: List<Data> = listOf()) : Data() | |
} | |
data class Compare(val first: Data, val second: Data) | |
fun String.findClosingBracketFromPos(openBracketPos: Int): Int { | |
var closedBracketPos = openBracketPos | |
var counter = 1 | |
while (counter > 0) { | |
when (this[++closedBracketPos]) { | |
']' -> counter-- | |
'[' -> counter++ | |
} | |
} | |
return closedBracketPos | |
} | |
fun String.parseLine(): Data { | |
val list = mutableListOf<Data>() | |
var index = 0 | |
while (index < count()) { | |
when (val char = this[index]) { | |
'[' -> { | |
val closedPos = this.findClosingBracketFromPos(index) | |
val sub = substring(startIndex = index + 1, endIndex = closedPos) | |
list.add(sub.parseLine()) | |
index = closedPos | |
} | |
',' -> {} | |
else -> list.add(Data.Integer(char.digitToInt())) | |
} | |
index++ | |
} | |
return Data.ListData(list) | |
} | |
fun parseInput(input: () -> List<String>): List<Compare> = input().chunked(2).map { | |
Compare( | |
it.component1().parseLine(), | |
it.component2().parseLine() | |
) | |
} | |
sealed class Result { | |
object CorrectOrder : Result() | |
object IncorrectOrder : Result() | |
object Tie : Result() | |
} | |
fun Data.Integer.compare(other: Data.Integer) = when { | |
this.value < other.value -> Result.CorrectOrder | |
this.value > other.value -> Result.IncorrectOrder | |
else -> Result.Tie | |
} | |
fun Data.ListData.compare(other: Data.ListData): Result { | |
val firstIterator = this.data.iterator() | |
val secondIterator = other.data.iterator() | |
while (firstIterator.hasNext() && secondIterator.hasNext()) { | |
val firstNext = firstIterator.next() | |
val secondNext = secondIterator.next() | |
when (val result = Compare(firstNext, secondNext).eval()) { | |
Result.Tie -> continue | |
else -> return result | |
} | |
} | |
// in case one ran out of items first we need to check which one it was | |
return when { | |
firstIterator.hasNext() && !secondIterator.hasNext() -> Result.IncorrectOrder | |
secondIterator.hasNext() && !firstIterator.hasNext() -> Result.CorrectOrder | |
this.data.count() == other.data.count() -> Result.Tie | |
else -> error("") | |
} | |
} | |
fun Compare.eval(): Result = when { | |
first is Data.Integer && second is Data.Integer -> first.compare(second) | |
first is Data.ListData && second is Data.ListData -> first.compare(second) | |
first is Data.ListData && second is Data.Integer -> first.compare(Data.ListData(listOf(second))) | |
first is Data.Integer && second is Data.ListData -> Data.ListData(listOf(first)).compare(second) | |
else -> error("No such comparison scenario") | |
} | |
fun day131() = parseInput { input } | |
.mapIndexed { index, pair -> | |
when (pair.eval()) { | |
Result.CorrectOrder -> index + 1 | |
else -> 0 | |
} | |
}.sum() | |
fun main() { | |
println(day131()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment