Skip to content

Commit

Permalink
D22 Perf
Browse files Browse the repository at this point in the history
Removed use of 'windows', instead just loop through 0..1997, taking delta sublists and prices as we go. More efficient than getting all windows upfront then having to find them within the delta list again to get their index (30s > 2s)
  • Loading branch information
hibob224 committed Dec 22, 2024
1 parent 8ac0573 commit e97cebe
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 29 deletions.
13 changes: 13 additions & 0 deletions src/main/kotlin/utils/Extensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,16 @@ fun <T> Sequence<T>.repeat() = sequence {
}

fun isCi(): Boolean = System.getenv("CI").toBoolean()

/**
* Find index of [subList] within [mainList]
*/
fun findSubsequenceIndex(mainList: List<Long>, subList: List<Long>): Int {
if (subList.isEmpty()) return 0 // Empty subsequence is always found at the beginning

for (i in mainList.indices) {
if (i + subList.size > mainList.size) break // Avoid out-of-bounds access
if (mainList.subList(i, i + subList.size) == subList) return i
}
return -1
}
52 changes: 23 additions & 29 deletions src/main/kotlin/y2024/day22/Day22.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,30 @@ object Day22 {
}

fun solvePartTwo(): Long {
return input.map {
val deltas = mutableListOf<Long>(0)
val prices = mutableListOf(it % 10)
var secret = it

repeat(2000) {
secret = secret.nextSecret()
val price = secret % 10
deltas += price - prices.last()
prices += price
}

val windows = deltas.windowed(4).toSet()
windows.map { window ->
val index = findSubsequenceIndex(deltas, window)
window to prices.getOrElse(index + 3) { -1 }
return input
.map { start ->
val deltas = mutableListOf<Long>(0)
val prices = mutableListOf(start % 10)
var secret = start

repeat(2000) {
secret = secret.nextSecret()
val price = secret % 10
deltas += price - prices.last()
prices += price
}

(0..1997)
.mapNotNull { idx ->
val window = deltas.subList(idx, idx + 4)
val price = prices.getOrNull(idx + 3)
price?.let { window to it }
}.distinctBy { it.first }
}
}.flatten().groupingBy { it.first }.fold(0L) { acc, i ->
acc + i.second
}.maxOf { it.value }
.flatten()
.groupingBy { it.first }
.fold(0L) { acc, i -> acc + i.second }
.maxOf { it.value }
}

private fun Long.nextSecret(): Long {
Expand All @@ -51,14 +55,4 @@ object Day22 {

private fun Long.mix(l2: Long): Long = this xor l2
private fun Long.prune(): Long = this % 16777216

fun findSubsequenceIndex(mainList: List<Long>, subList: List<Long>): Int {
if (subList.isEmpty()) return 0 // Empty subsequence is always found at the beginning

for (i in mainList.indices) {
if (i + subList.size > mainList.size) break // Avoid out-of-bounds access
if (mainList.subList(i, i + subList.size) == subList) return i
}
return -1
}
}

0 comments on commit e97cebe

Please sign in to comment.