From c9f14cf804394aa83f86ac693887d23cc4913318 Mon Sep 17 00:00:00 2001 From: Daniel Lin Date: Wed, 21 Dec 2022 14:41:46 -0500 Subject: [PATCH] Simpler way of iterating through powerset --- .../com/github/ephemient/aoc2022/Day16.kt | 69 ++++++++----------- 1 file changed, 27 insertions(+), 42 deletions(-) diff --git a/kt/src/commonMain/kotlin/com/github/ephemient/aoc2022/Day16.kt b/kt/src/commonMain/kotlin/com/github/ephemient/aoc2022/Day16.kt index 630a2b8..0d04a22 100644 --- a/kt/src/commonMain/kotlin/com/github/ephemient/aoc2022/Day16.kt +++ b/kt/src/commonMain/kotlin/com/github/ephemient/aoc2022/Day16.kt @@ -86,51 +86,36 @@ class Day16(lines: List) { } if (movesByTime.values.all { movesByAgent -> movesByAgent.all { it.isEmpty() } }) continue for ((d, movesByAgent) in movesByTime) { - for (bitmask in 1 until 1.shl(agents)) { - run { // https://youtrack.jetbrains.com/issue/KT-1436 - val indices = IntArray(agents) { i -> - if (bitmask and 1.shl(i) != 0) { - if (movesByAgent[i].isEmpty()) return@run - 0 + val indices = IntArray(agents) { -1 } + while ( + indices.withIndex().any { (i, j) -> + (if (j < movesByAgent[i].lastIndex) j + 1 else -1).also { indices[i] = it } >= 0 + } + ) { + val allUnique: Boolean + val valves = buildSet { + allUnique = indices.withIndex().all { (i, j) -> j < 0 || add(movesByAgent[i][j]) } + } + if (allUnique) { + val rooms = indices.mapIndexed { i, j -> + if (j >= 0) { + IndexedValue(0, movesByAgent[i][j]) } else { - -1 + val (age, room) = state.rooms[i] + IndexedValue(age + d + 1, room) } + }.sortedWith(compareBy({ it.value }, { it.index })) + val rate = indices.withIndex().sumOf { (i, j) -> + if (j >= 0) graph.getValue(movesByAgent[i][j]).index else 0 } - do { - var allUnique = true - val valves = buildSet { - indices.forEachIndexed { i, j -> - if (j >= 0) allUnique = add(movesByAgent[i][j]) && allUnique - } - } - if (allUnique) { - val rooms = indices.mapIndexed { i, j -> - if (j >= 0) { - IndexedValue(0, movesByAgent[i][j]) - } else { - val (age, room) = state.rooms[i] - IndexedValue(age + d + 1, room) - } - }.sortedWith(compareBy({ it.value }, { it.index })) - val rate = indices.withIndex().sumOf { (i, j) -> - if (j >= 0) graph.getValue(movesByAgent[i][j]).index else 0 - } - val newState = State( - rooms = rooms, - valves = state.valves - valves, - flow = state.flow + rate, - total = state.total + state.flow * (d + 1), - timeRemaining = state.timeRemaining - d - 1, - ) - queue.add(IndexedValue(estimate + rate * newState.timeRemaining, newState)) - } - val allIsAtEnd = indices.withIndex().all { (i, j) -> - if (j < 0) return@all true - val isAtEnd = j == movesByAgent[i].lastIndex - indices[i] = if (isAtEnd) 0 else j + 1 - isAtEnd - } - } while (!allIsAtEnd) + val newState = State( + rooms = rooms, + valves = state.valves - valves, + flow = state.flow + rate, + total = state.total + state.flow * (d + 1), + timeRemaining = state.timeRemaining - d - 1, + ) + queue.add(IndexedValue(estimate + rate * newState.timeRemaining, newState)) } } }