Compare commits
No commits in common. "d793a4780169084fc8a4ff5037407a1a3473e874" and "59dfc17ee1d02c1a91f1a936e1015dc7275af16c" have entirely different histories.
d793a47801
...
59dfc17ee1
@ -1,118 +0,0 @@
|
|||||||
package be.vandewalleh.aoc.days
|
|
||||||
|
|
||||||
import be.vandewalleh.aoc.utils.input.Day
|
|
||||||
import be.vandewalleh.aoc.utils.input.Input
|
|
||||||
import be.vandewalleh.aoc.utils.input.Text
|
|
||||||
import be.vandewalleh.aoc.utils.input.createDay
|
|
||||||
|
|
||||||
@Day(23)
|
|
||||||
class Day23(@Text val input: Input<String>) {
|
|
||||||
private val cups = input.value.toCharArray().map { it.toString().toInt() }
|
|
||||||
|
|
||||||
private fun <T> ringSequence(head: Ring.Node<T>) = generateSequence(head) { it.next }
|
|
||||||
|
|
||||||
class Ring<T>(items: Iterable<T>) {
|
|
||||||
|
|
||||||
class Node<T>(var value: T) {
|
|
||||||
lateinit var next: Node<T>
|
|
||||||
override fun toString() = "Node($value -> ${next.value})"
|
|
||||||
}
|
|
||||||
|
|
||||||
private var last: Node<T>? = null
|
|
||||||
private var first: Node<T>? = null
|
|
||||||
|
|
||||||
init {
|
|
||||||
items.forEach { item ->
|
|
||||||
val node = Node(item)
|
|
||||||
if (first == null) first = node
|
|
||||||
last?.next = node
|
|
||||||
last = node
|
|
||||||
}
|
|
||||||
check(first != null && last != null)
|
|
||||||
last?.next = first!!
|
|
||||||
}
|
|
||||||
|
|
||||||
fun first() = first!!
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Ring.Node<Int>.cached(size: Int): Array<Ring.Node<Int>> =
|
|
||||||
arrayOfNulls<Ring.Node<Int>>(size + 1).also { array ->
|
|
||||||
array[0] = Ring.Node(-1)
|
|
||||||
ringSequence(this).take(size).forEach { array[it.value] = it }
|
|
||||||
} as Array<Ring.Node<Int>>
|
|
||||||
|
|
||||||
fun part1(): String {
|
|
||||||
var currentNode = Ring(cups).first()
|
|
||||||
val cache = currentNode.cached(cups.size)
|
|
||||||
val max = cups.maxOrNull()!!
|
|
||||||
|
|
||||||
repeat(100) { currentNode = move(max, cache, currentNode) }
|
|
||||||
|
|
||||||
return ringSequence(currentNode)
|
|
||||||
.dropWhile { it.value != 1 }
|
|
||||||
.drop(1)
|
|
||||||
.take(cups.size - 1)
|
|
||||||
.map { it.value }
|
|
||||||
.joinToString("")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun part2(): Long {
|
|
||||||
fun fillCups(): List<Int> {
|
|
||||||
val cups = ArrayList<Int>(1_000_000)
|
|
||||||
cups.addAll(this.cups)
|
|
||||||
val highest = this.cups.maxOrNull()!!
|
|
||||||
|
|
||||||
for (i in 1..1_000_000 - cups.size) {
|
|
||||||
cups.add(highest + i)
|
|
||||||
}
|
|
||||||
|
|
||||||
return cups
|
|
||||||
}
|
|
||||||
|
|
||||||
val size = 1_000_000
|
|
||||||
var currentNode = Ring(fillCups()).first()
|
|
||||||
val cache = currentNode.cached(size)
|
|
||||||
|
|
||||||
repeat(10_000_000) { currentNode = move(max = size, cache, currentNode) }
|
|
||||||
|
|
||||||
val one = cache[1]
|
|
||||||
val a = one.next
|
|
||||||
val b = a.next
|
|
||||||
return a.value.toLong() * b.value.toLong()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun move(max: Int, cache: Array<Ring.Node<Int>>, current: Ring.Node<Int>): Ring.Node<Int> {
|
|
||||||
val a = current.next
|
|
||||||
val b = a.next
|
|
||||||
val c = b.next
|
|
||||||
|
|
||||||
current.next = c.next
|
|
||||||
|
|
||||||
val aa = a.value
|
|
||||||
val bb = b.value
|
|
||||||
val cc = c.value
|
|
||||||
|
|
||||||
val destinationNode: Ring.Node<Int>
|
|
||||||
var i = current.value - 1
|
|
||||||
while (true) {
|
|
||||||
if (i < 1) i = max
|
|
||||||
val value = cache[i].value
|
|
||||||
if (value == aa || value == bb || value == cc) {
|
|
||||||
i--
|
|
||||||
} else {
|
|
||||||
destinationNode = cache[i]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val destinationNextNode = destinationNode.next
|
|
||||||
destinationNode.next = a
|
|
||||||
c.next = destinationNextNode
|
|
||||||
return current.next
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun main() = with(createDay<Day23>()) {
|
|
||||||
println(part1())
|
|
||||||
println(part2())
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
871369452
|
|
||||||
Loading…
x
Reference in New Issue
Block a user