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)
|