diff --git a/Assignments/Sorting/ShellSort.playground/Pages/Shell Sort.xcplaygroundpage/Contents.swift b/Assignments/Sorting/ShellSort.playground/Pages/Shell Sort.xcplaygroundpage/Contents.swift index 5161e34..9ad8b33 100644 --- a/Assignments/Sorting/ShellSort.playground/Pages/Shell Sort.xcplaygroundpage/Contents.swift +++ b/Assignments/Sorting/ShellSort.playground/Pages/Shell Sort.xcplaygroundpage/Contents.swift @@ -16,22 +16,22 @@ class ShellSequence: SequenceType { } func generate() -> AnyGenerator { - // YOUR CODE + var number = self.n return anyGenerator { - // YOUR CODE - - nil + number = number / 2 + return number > 0 ? number : nil } } } + //: Test your code with assert. Make sure asserts don't raise any errors. -//assert(Array(ShellSequence(n: 20)) == [10, 5, 2, 1]) -//assert(Array(ShellSequence(n: 9)) == [4, 2, 1]) -//assert(Array(ShellSequence(n: 2)) == [1]) -//assert(Array(ShellSequence(n: 1)) == []) +assert(Array(ShellSequence(n: 20)) == [10, 5, 2, 1]) +assert(Array(ShellSequence(n: 9)) == [4, 2, 1]) +assert(Array(ShellSequence(n: 2)) == [1]) +assert(Array(ShellSequence(n: 1)) == []) /*: @@ -41,6 +41,13 @@ class ShellSequence: SequenceType { Write a similar class to create a gap sequence of (3 ^ k - 1) / 2) going as 1, 4, 13, 40, ... We will use the elements less than n in reversed order. For example if n is 200, the sequence should be [121, 40, 13, 4, 1]. */ +// Defining ^ operator +infix operator ** { associativity left precedence 170 } +func ** (num: Int, power: Int) -> Int { + let numDouble = Double(num) + let powerDouble = Double(power) + return Int(pow(numDouble, powerDouble)) +} class KnuthSequence: SequenceType { let n: Int @@ -51,14 +58,29 @@ class KnuthSequence: SequenceType { func generate() -> AnyGenerator { + var index = 1 + + while (3 ** index - 1) / 2 < self.n { + index += 1 + } + + index -= 1 + + var number = (3 ** index - 1) / 2 + return anyGenerator { - nil + print("index: \(index)") + print("number: \(number)") + number = (3 ** index - 1) / 2 + index -= 1 + return number > 0 ? number : nil } } } -//assert(Array(KnuthSequence(n: 200)) == [121, 40, 13, 4, 1]) -//assert(Array(KnuthSequence(n: 10)) == [4, 1]) +// This assert (and the next ones) fails and I don't know why +assert(Array(KnuthSequence(n: 200)) == [121, 40, 13, 4, 1]) +assert(Array(KnuthSequence(n: 10)) == [4, 1]) /*: @@ -70,8 +92,28 @@ Write a shell sort by using one of the generators you created above. Knuth's gap func shellSort(var array: [T], isOrderedBefore: (T, T) -> Bool) -> [T] { - for i in KnuthSequence(n: array.count) { + + + for gap in KnuthSequence(n: array.count) { + print("new smaller gap: \(gap)") + + var index = 0 + var otherIndex = index + gap + + while otherIndex < array.count { + print("checking \(array[index]) and \(array[otherIndex])") + if isOrderedBefore(array[index], array[otherIndex]) == false { + swap(&array[index], &array[otherIndex]) + print("swapped \(array[index]) with \(array[otherIndex])") + index = 0 + otherIndex = index + gap + } else { + index += 1 + otherIndex += 1 + print("index + 1") + } + } } return array @@ -79,7 +121,7 @@ func shellSort(var array: [T], isOrderedBefore: (T, T) -> Bool) -> [T] { let items = ["c", "d", "b", "a"] let sortedItems = shellSort(items, isOrderedBefore: <) -//assert(sortedItems.isSorted()) +assert(sortedItems.isSorted()) assert(items == ["c", "d", "b", "a"]) // double check that items does not change assert(shellSort([Int](), isOrderedBefore: <).isSorted())