From 4091d3f083cd071be90f845ad1d39cf511199bd9 Mon Sep 17 00:00:00 2001 From: Daniel Dahan Date: Fri, 18 Nov 2016 14:27:06 -0600 Subject: [PATCH] development: Algorithm ready for Swift 3 release --- Sources/Queue.swift | 12 +++--- Sources/RedBlackTree.swift | 62 +++++++++++++++-------------- Sources/SortedMultiDictionary.swift | 5 ++- Sources/Stack.swift | 12 +++--- Tests/QueueTests.swift | 10 ++--- Tests/RedBlackTreeTests.swift | 21 +++++----- Tests/StackTests.swift | 8 ++-- 7 files changed, 69 insertions(+), 61 deletions(-) diff --git a/Sources/Queue.swift b/Sources/Queue.swift index 6126ff2..9e98efc 100644 --- a/Sources/Queue.swift +++ b/Sources/Queue.swift @@ -28,7 +28,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -public class Queue: CustomStringConvertible, Sequence { +public struct Queue: CustomStringConvertible, Sequence { public typealias Iterator = AnyIterator /** @@ -97,7 +97,7 @@ public class Queue: CustomStringConvertible, Sequence { :name: enqueue :description: Insert a new element at the back of the Queue. */ - public func enqueue(_ element: Element) { + mutating public func enqueue(_ element: Element) { list.insert(atBack: element) } @@ -107,7 +107,7 @@ public class Queue: CustomStringConvertible, Sequence { of the Queue. - returns: Element? */ - public func dequeue() -> Element? { + mutating public func dequeue() -> Element? { return list.removeAtFront() } @@ -115,13 +115,13 @@ public class Queue: CustomStringConvertible, Sequence { :name: removeAll :description: Remove all elements from the Queue. */ - public func removeAll() { + mutating public func removeAll() { list.removeAll() } } public func +(lhs: Queue, rhs: Queue) -> Queue { - let q = Queue() + var q = Queue() for x in lhs { q.enqueue(x) } @@ -131,7 +131,7 @@ public func +(lhs: Queue, rhs: Queue) -> Queue(lhs: Queue, rhs: Queue) { +public func +=(lhs: inout Queue, rhs: Queue) { for x in rhs { lhs.enqueue(x) } diff --git a/Sources/RedBlackTree.swift b/Sources/RedBlackTree.swift index bb29d11..36e1c7c 100644 --- a/Sources/RedBlackTree.swift +++ b/Sources/RedBlackTree.swift @@ -325,7 +325,7 @@ public struct RedBlackTree: Probable, Collection, Custom the given key value will be updated. */ mutating public func update(value: Value?, for key: Key) { - internalUpdateValue(value, forKey: key, node: root) + internalUpdateValue(value, for: key, node: root) } /** @@ -348,11 +348,11 @@ public struct RedBlackTree: Probable, Collection, Custom */ public subscript(index: Int) -> (key: Key, value: Value?) { get { - let x = internalSelect(root, order: index + 1) + let x = internalSelect(root, order: index + 1) return (x.key, x.value) } set(element) { - internalUpdateValue(element.value, forKey: element.key, node: root) + internalUpdateValue(element.value, for: element.key, node: root) } } @@ -368,7 +368,7 @@ public struct RedBlackTree: Probable, Collection, Custom return internalFindNodeForKey(key).value } set(value) { - if sentinel == internalFindNodeForKey(key) { + if sentinel === internalFindNodeForKey(key) { _ = internalInsert(key, value: value) } else { update(value: value, for: key) @@ -383,7 +383,7 @@ public struct RedBlackTree: Probable, Collection, Custom */ public func index(of key: Key) -> Int { let x = internalFindNodeForKey(key) - return sentinel == x ? -1 : internalOrder(x) - 1 + return sentinel === x ? -1 : internalOrder(x) - 1 } /** @@ -407,7 +407,7 @@ public struct RedBlackTree: Probable, Collection, Custom let z = RedBlackNode(parent: y, sentinel: sentinel, key: key, value: value) - if y == sentinel { + if y === sentinel { root = z } else if key < y.key as Key { y.left = z @@ -428,7 +428,7 @@ public struct RedBlackTree: Probable, Collection, Custom mutating private func insertCleanUp(_ node: RedBlackNode) { var z = node while z.parent.isRed { - if z.parent == z.parent.parent.left { + if z.parent === z.parent.parent.left { let y = z.parent.parent.right! // violation 1, parent child relationship re to isRed if y.isRed { @@ -438,7 +438,7 @@ public struct RedBlackTree: Probable, Collection, Custom z = z.parent.parent } else { // case 2, parent is isRed, uncle is black - if z == z.parent.right { + if z === z.parent.right { z = z.parent leftRotate(z) } @@ -458,7 +458,7 @@ public struct RedBlackTree: Probable, Collection, Custom z = z.parent.parent } else { // case 2, parent is isRed, uncle is black - if z == z.parent.left { + if z === z.parent.left { z = z.parent rightRotate(z) } @@ -481,7 +481,7 @@ public struct RedBlackTree: Probable, Collection, Custom @discardableResult mutating private func internalRemoveValueForKey(_ key: Key) -> RedBlackNode { let z = internalFindNodeForKey(key) - if z == sentinel { + if z === sentinel { return sentinel } @@ -498,17 +498,17 @@ public struct RedBlackTree: Probable, Collection, Custom var y = z var isRed: Bool = y.isRed - if z.left == sentinel { + if z.left === sentinel { x = z.right transplant(z, v: z.right) - } else if z.right == sentinel { + } else if z.right === sentinel { x = z.left transplant(z, v: z.left) } else { y = minimum(z.right) isRed = y.isRed x = y.right - if y.parent == z { + if y.parent === z { x.parent = y } else { transplant(y, v: y.right) @@ -542,7 +542,7 @@ public struct RedBlackTree: Probable, Collection, Custom mutating private func removeCleanUp(_ node: RedBlackNode) { var x = node while x !== root && !x.isRed { - if x == x.parent.left { + if x === x.parent.left { var y = x.parent.right! if y.isRed { y.isRed = false @@ -615,9 +615,9 @@ public struct RedBlackTree: Probable, Collection, Custom :description: Swaps two subTrees in the tree. */ mutating private func transplant(_ u: RedBlackNode, v: RedBlackNode) { - if u.parent == sentinel { + if u.parent === sentinel { root = v - } else if u == u.parent.left { + } else if u === u.parent.left { u.parent.left = v } else { u.parent.right = v @@ -640,9 +640,9 @@ public struct RedBlackTree: Probable, Collection, Custom y.parent = x.parent - if sentinel == x.parent { + if sentinel === x.parent { root = y - } else if x == x.parent.left { + } else if x === x.parent.left { x.parent.left = y } else { x.parent.right = y @@ -669,9 +669,9 @@ public struct RedBlackTree: Probable, Collection, Custom x.parent = y.parent - if sentinel == y.parent { + if sentinel === y.parent { root = x - } else if y == y.parent.right { + } else if y === y.parent.right { y.parent.right = x } else { y.parent.left = x @@ -733,13 +733,13 @@ public struct RedBlackTree: Probable, Collection, Custom :name: internalUpdateValue :description: Traverses the Tree and updates all the values that match the key. */ - private func internalUpdateValue(_ value: Value?, forKey: Key, node: RedBlackNode) { + private func internalUpdateValue(_ value: Value?, for key: Key, node: RedBlackNode) { if node !== sentinel { - if forKey == node.key { + if key == node.key { node.value = value } - internalUpdateValue(value, forKey: forKey, node: node.left) - internalUpdateValue(value, forKey: forKey, node: node.right) + internalUpdateValue(value, for: key, node: node.left) + internalUpdateValue(value, for: key, node: node.right) } } @@ -752,7 +752,7 @@ public struct RedBlackTree: Probable, Collection, Custom var x = node var r: Int = x.left.order + 1 while root !== x { - if x.parent.right == x { + if x.parent.right === x { r += x.parent.left.order + 1 } x = x.parent @@ -765,14 +765,15 @@ public struct RedBlackTree: Probable, Collection, Custom :description: Validates the order statistic being within range of 1...n. */ private func validateOrder(_ order: Int) { - assert(order >= startIndex || order < endIndex, "[Algorithm Error: Order out of bounds.]") + assert(order > startIndex || order <= endIndex, "[Algorithm Error: Order out of bounds.]") } } public func ==(lhs: RedBlackTree, rhs: RedBlackTree) -> Bool { - if lhs.count != rhs.count { + guard lhs.count == rhs.count else { return false } + for i in 0..(lhs: RedBlackTree, rhs: RedB } public func +(lhs: RedBlackTree, rhs: RedBlackTree) -> RedBlackTree { - var t = lhs - for (k, v) in rhs { + var t = RedBlackTree() + for (k, v) in lhs { + t.insert(value: v, for: k) + } + for (k, v) in rhs { t.insert(value: v, for: k) } return t diff --git a/Sources/SortedMultiDictionary.swift b/Sources/SortedMultiDictionary.swift index b947e71..adcd624 100644 --- a/Sources/SortedMultiDictionary.swift +++ b/Sources/SortedMultiDictionary.swift @@ -380,7 +380,10 @@ public func !=(lhs: SortedMultiDictionary, } public func +(lhs: SortedMultiDictionary, rhs: SortedMultiDictionary) -> SortedMultiDictionary { - var t = lhs + var t = SortedMultiDictionary() + for (k, v) in lhs { + t.insert(value: v, for: k) + } for (k, v) in rhs { t.insert(value: v, for: k) } diff --git a/Sources/Stack.swift b/Sources/Stack.swift index 8fd96f1..0e643aa 100644 --- a/Sources/Stack.swift +++ b/Sources/Stack.swift @@ -28,7 +28,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -public class Stack: CustomStringConvertible, Sequence { +public struct Stack: CustomStringConvertible, Sequence { public typealias Iterator = AnyIterator /// Underlying data structure. @@ -72,7 +72,7 @@ public class Stack: CustomStringConvertible, Sequence { Insert a new element at the top of the Stack. - Parameter _ element: An Element type. */ - public func push(_ element: Element) { + mutating public func push(_ element: Element) { list.insert(atFront: element) } @@ -81,18 +81,18 @@ public class Stack: CustomStringConvertible, Sequence { the Stack. - Returns: Element? */ - public func pop() -> Element? { + mutating public func pop() -> Element? { return list.removeAtFront() } /// Remove all elements from the Stack. - public func removeAll() { + mutating public func removeAll() { list.removeAll() } } public func +(lhs: Stack, rhs: Stack) -> Stack { - let s = Stack() + var s = Stack() for x in lhs { s.push(x) } @@ -102,7 +102,7 @@ public func +(lhs: Stack, rhs: Stack) -> Stack(lhs: Stack, rhs: Stack) { +public func +=(lhs: inout Stack, rhs: Stack) { for x in rhs { lhs.push(x) } diff --git a/Tests/QueueTests.swift b/Tests/QueueTests.swift index 02df128..b674f33 100644 --- a/Tests/QueueTests.swift +++ b/Tests/QueueTests.swift @@ -42,7 +42,7 @@ class QueueTests: XCTestCase { } func testInt() { - let q: Queue = Queue() + var q = Queue() q.enqueue(1) q.enqueue(2) @@ -78,17 +78,17 @@ class QueueTests: XCTestCase { } func testConcat() { - let q1: Queue = Queue() + var q1 = Queue() q1.enqueue(1) q1.enqueue(2) q1.enqueue(3) - let q2: Queue = Queue() + var q2 = Queue() q2.enqueue(4) q2.enqueue(5) q2.enqueue(6) - let q3: Queue = q1 + q2 + var q3 = q1 + q2 for x in q1 { XCTAssert(x == q3.dequeue(), "Concat incorrect.") @@ -99,7 +99,7 @@ class QueueTests: XCTestCase { } q3.removeAll() - let q4: Queue = q1 + q2 + q3 + var q4 = q1 + q2 + q3 for x in q4 { XCTAssert(x == q4.dequeue(), "Concat incorrect.") } diff --git a/Tests/RedBlackTreeTests.swift b/Tests/RedBlackTreeTests.swift index 389a591..b8f7b7c 100644 --- a/Tests/RedBlackTreeTests.swift +++ b/Tests/RedBlackTreeTests.swift @@ -65,13 +65,13 @@ class RedBlackTreeTests: XCTestCase { XCTAssert(1 == s.count, "Test failed.") s.removeValue(for: 2) - XCTAssert(true == s.insert(value: 2, for: 10), "Test failed.") - XCTAssert(1 == s.count, "Test failed.") - XCTAssert(10 == s.findValue(for: 2), "Test failed.") - XCTAssert(10 == s[0].value, "Test failed.") + XCTAssert(true == s.insert(value: 10, for: 2), "Test failed.") + XCTAssertEqual(1, s.count, "Test failed.") + XCTAssertEqual(10, s.findValue(for: 2), "Test failed.") + XCTAssertEqual(10, s[0].value, "Test failed.") s.removeValue(for: 2) - XCTAssert(0 == s.count, "Test failed.") + XCTAssertEqual(0, s.count, "Test failed.") s.insert(value: 1, for: 1) s.insert(value: 2, for: 2) @@ -155,17 +155,18 @@ class RedBlackTreeTests: XCTestCase { func testOperands() { var t1 = RedBlackTree(uniqueKeys: true) t1.insert((1, 1), (2, 2), (3, 3), (4, 4)) - XCTAssert(4 == t1.count, "Test failed.") + XCTAssertEqual(4, t1.count, "Test failed.") var t2 = RedBlackTree(uniqueKeys: true) t2.insert((5, 5), (6, 6), (7, 7), (8, 8)) - XCTAssert(4 == t2.count, "Test failed.") - - let t3 = t1 + t2 - XCTAssert(8 == t3.count, "Test failed.") + XCTAssertEqual(4, t2.count, "Test failed.") + + let t3 = t1 + t2 + XCTAssertEqual(8, t3.count, "Test failed.") XCTAssert(t1 != t2, "Test failed.") XCTAssert(t3 != t2, "Test failed.") + XCTAssert(t3 == (t1 + t2), "Test failed.") } diff --git a/Tests/StackTests.swift b/Tests/StackTests.swift index 3b9915a..a3b9536 100644 --- a/Tests/StackTests.swift +++ b/Tests/StackTests.swift @@ -42,7 +42,7 @@ class StackTests: XCTestCase { } func testInt() { - let s: Stack = Stack() + var s = Stack() s.push(1) s.push(2) @@ -74,17 +74,17 @@ class StackTests: XCTestCase { } func testConcat() { - let s1: Stack = Stack() + var s1 = Stack() s1.push(1) s1.push(2) s1.push(3) - let s2: Stack = Stack() + var s2 = Stack() s2.push(4) s2.push(5) s2.push(6) - let s3: Stack = s1 + s2 + let s3 = s1 + s2 XCTAssert(6 == s3.count, "Concat incorrect.") }