This repository has been archived by the owner on Jul 16, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday23.kt
99 lines (90 loc) · 3.11 KB
/
day23.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import kotlin.math.*
private val Int.needId get() = when (this) {
1 -> 2
10 -> 4
100 -> 6
1000 -> 8
else -> TODO()
}
private data class Day23State(val a:List<List<Int?>>, val c:List<Int?>) {
fun final() = c.all { it == null } &&
a.indices.all { index -> a[index].all{ it != null && it.needId == index } }
fun moveFromC(index: Int) : Pair<Day23State, Int>? {
val to = c[index]?.needId ?: return null
val top = a[to].indexOfFirst { it == null }.takeIf { it >= 0 } ?: return null
return when {
a[to].any { it != null && it.needId != to } -> null
index < to && (index + 1 until to).any { c[it] != null } -> null
index > to && (to + 1 until index).any { c[it] != null } -> null
else -> Day23State(
a.replace(to, a[to].replace(top, c[index])),
c.replace(index, null)
) to (c[index]!! * (a[to].size - top + abs(index - to)))
}
}
fun moveToC(from: Int, index:Int): Pair<Day23State, Int>? {
val top = a[from].indexOfLast { it != null }.takeIf { it >= 0 } ?: return null
return when {
c[index] != null -> null
a[from].all { it == null || it.needId == from } -> null
index < from && (index + 1 until from).any { c[it] != null } -> null
index > from && (from + 1 until index).any { c[it] != null } -> null
else -> Day23State(
a.replace(from, a[from].replace(top, null)),
c.replace(index, a[from][top])
) to (a[from][top]!! * (abs(index - from) + a[from].size - top))
}
}
}
fun main() {
val easyData = Day23State(
listOf(
emptyList(),
emptyList(),
listOf(1000, 1),
emptyList(),
listOf(1, 100),
emptyList(),
listOf(1000, 10),
emptyList(),
listOf(10, 100),
emptyList(),
emptyList()
),
arrayOfNulls<Int?>(11).toList()
)
val hardData = Day23State(
listOf(
emptyList(),
emptyList(),
listOf(1000, 1000, 1000, 1),
emptyList(),
listOf(1, 10, 100, 100),
emptyList(),
listOf(1000, 1, 10, 10),
emptyList(),
listOf(10, 100, 1, 100),
emptyList(),
emptyList()
),
arrayOfNulls<Int?>(11).toList()
)
println(solve(easyData))
cache.clear()
println(solve(hardData))
}
private val cache = mutableMapOf<Any, Int>()
private val fromList = listOf(0, 1, 3, 5, 7, 9, 10)
private val toList = fromList.flatMap { f -> listOf(2, 4, 6, 8).map { it to f } }
private fun solve(state: Day23State) : Int = cache.getOrPut(state) {
if (state.final())
0
else
fromList
.mapNotNull { state.moveFromC(it) }
.minOfOrNull { it.second + solve(it.first) }
?: toList
.mapNotNull { state.moveToC(it.first, it.second) }
.minOfOrNull { it.second + solve(it.first) }
?: (Int.MAX_VALUE / 2)
}