Rewrite using linked list

This commit is contained in:
Sven Weidauer 2020-12-24 09:00:09 +01:00
parent 395c30a952
commit 35353b8641

View file

@ -1,36 +1,97 @@
var stack = [9, 5, 2, 3, 1, 6, 4, 8, 7] class Node {
var next: Node!
var value: Int
extension Array { init(value: Int, next: Node? = nil) {
mutating func rotateLeft(mid: Index) { self.value = value
let slice = self[0..<mid] self.next = next
removeSubrange(0..<mid)
append(contentsOf: slice)
} }
static func make(_ values: [Int]) -> Node {
precondition(!values.isEmpty)
let first = Node(value: values[0])
first.next = first
var current = first
for value in values.dropFirst() {
let new = Node(value: value, next: first)
current.next = new
current = new
}
return first
}
func find(value: Int) -> Node? {
var current = self
repeat {
if current.value == value {
return current
}
current = current.next
} while current !== self
return nil
}
}
let input = [9, 5, 2, 3, 1, 6, 4, 8, 7]
let max = input.max()!
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
} }
func round() { func round() {
let picked = stack[1 ... 3] let firstPick: Node = selected.next
stack.removeSubrange(1 ... 3) let lastPick: Node = firstPick.next.next
var destination = stack[0] selected.next = lastPick.next
var destination = selected.value
repeat { repeat {
destination -= 1 destination -= 1
if destination < 1 { if destination < 1 {
destination = 9 destination = max
} }
} while picked.contains(destination) } while rangeContains(value: destination, start: firstPick, end: lastPick)
let destinationIndex = stack.firstIndex(of: destination)! + 1 let toInsert = lastPick.next.find(value: destination)!
stack.insert(contentsOf: picked, at: destinationIndex) lastPick.next = toInsert.next
toInsert.next = firstPick
stack.rotateLeft(mid: 1) selected = selected.next
} }
func printStack() { func printStack() {
for (offset, value) in stack.enumerated() { var current = node
print(offset == 0 ? "(\(value))" : "\(value)", terminator: " ") 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
} }
print() print()
} }
for i in 0..<100 { for i in 0..<100 {
@ -38,9 +99,7 @@ for i in 0..<100 {
printStack() printStack()
round() round()
} }
print("Final: ", terminator: "") print("Final: ", terminator: "")
printStack() printStack()
showSolution()
let oneIndex = stack.firstIndex(of: 1)!
stack.rotateLeft(mid: (oneIndex + 1) % stack.count)
print(stack.dropLast().map {"\($0)"}.joined())