AoC/2020/day23/main.swift

113 lines
2.5 KiB
Swift
Raw Permalink Normal View History

2020-12-24 10:33:29 +01:00
var nodesByValue: [Node?] = Array(repeating: nil, count: 1000001)
final class Node {
2020-12-24 09:00:09 +01:00
var next: Node!
var value: Int
2020-12-24 07:58:28 +01:00
2020-12-24 09:00:09 +01:00
init(value: Int, next: Node? = nil) {
self.value = value
self.next = next
}
static func make(_ values: [Int]) -> Node {
precondition(!values.isEmpty)
let first = Node(value: values[0])
2020-12-24 10:33:29 +01:00
nodesByValue[values[0]] = first
2020-12-24 09:00:09 +01:00
first.next = first
var current = first
for value in values.dropFirst() {
let new = Node(value: value, next: first)
2020-12-24 10:33:29 +01:00
nodesByValue[value] = new
current.next = new
current = new
}
for value in 10...1000000 {
let new = Node(value: value, next: first)
nodesByValue[value] = new
2020-12-24 09:00:09 +01:00
current.next = new
current = new
}
return first
}
func find(value: Int) -> Node? {
2020-12-24 10:33:29 +01:00
return nodesByValue[value]
2020-12-24 07:58:28 +01:00
}
}
2020-12-24 09:00:09 +01:00
let input = [9, 5, 2, 3, 1, 6, 4, 8, 7]
2020-12-24 10:33:29 +01:00
let max = 1000000
//let max = input.max()!
2020-12-24 09:00:09 +01:00
let node = Node.make(input)
var selected = node
func rangeContains(value: Int, start: Node, end: Node) -> Bool {
var current = start
while current !== end.next {
if current.value == value {
return true
}
current = current.next
}
return false
}
2020-12-24 07:58:28 +01:00
func round() {
2020-12-24 09:00:09 +01:00
let firstPick: Node = selected.next
let lastPick: Node = firstPick.next.next
2020-12-24 07:58:28 +01:00
2020-12-24 09:00:09 +01:00
selected.next = lastPick.next
var destination = selected.value
2020-12-24 07:58:28 +01:00
repeat {
destination -= 1
if destination < 1 {
2020-12-24 09:00:09 +01:00
destination = max
2020-12-24 07:58:28 +01:00
}
2020-12-24 09:00:09 +01:00
} while rangeContains(value: destination, start: firstPick, end: lastPick)
2020-12-24 07:58:28 +01:00
2020-12-24 09:00:09 +01:00
let toInsert = lastPick.next.find(value: destination)!
lastPick.next = toInsert.next
toInsert.next = firstPick
2020-12-24 07:58:28 +01:00
2020-12-24 09:00:09 +01:00
selected = selected.next
2020-12-24 07:58:28 +01:00
}
func printStack() {
2020-12-24 09:00:09 +01:00
var current = node
repeat {
print(current === selected ? "(\(current.value))" : "\(current.value)", terminator: " ")
current = current.next
} while current !== node
print()
}
func showSolution() {
let start = node.find(value: 1)!
var one: Node = start.next
while one !== start {
print(one.value, terminator: "")
one = one.next
2020-12-24 07:58:28 +01:00
}
print()
2020-12-24 09:00:09 +01:00
2020-12-24 07:58:28 +01:00
}
2020-12-24 10:33:29 +01:00
for i in 0..<10_000_000 {
// print("\(i + 1)) ", terminator: "")
// printStack()
2020-12-24 07:58:28 +01:00
round()
}
2020-12-24 09:00:09 +01:00
2020-12-24 10:33:29 +01:00
//print("Final: ", terminator: "")
//printStack()
//showSolution()
let one = node.find(value: 1)!
print(one.next.value * one.next.next.value)