Skip to content

Commit 1823188

Browse files
Kelvin LauKelvin Lau
Kelvin Lau
authored and
Kelvin Lau
committed
"Catching up with new PRs"
2 parents 22ffeb2 + 5f8f384 commit 1823188

File tree

34 files changed

+510
-1492
lines changed

34 files changed

+510
-1492
lines changed

.travis.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,5 @@ script:
3838
# - xcodebuild test -project ./Shortest\ Path\ \(Unweighted\)/Tests/Tests.xcodeproj -scheme Tests
3939
# - xcodebuild test -project ./Single-Source\ Shortest\ Paths\ \(Weighted\)/SSSP.xcodeproj -scheme SSSPTests
4040
- xcodebuild test -project ./Stack/Tests/Tests.xcodeproj -scheme Tests
41-
# - xcodebuild test -project ./Topological\ Sort/Tests/Tests.xcodeproj -scheme Tests
41+
- xcodebuild test -project ./Topological\ Sort/Tests/Tests.xcodeproj -scheme Tests
42+
- xcodebuild test -project ./Treap/Treap/Treap.xcodeproj -scheme Tests

Boyer-Moore/BoyerMoore.playground/Contents.swift

+9-11
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,20 @@ extension String {
77
assert(patternLength <= self.characters.count)
88

99
var skipTable = [Character: Int]()
10-
for (i, c) in pattern.characters.enumerate() {
10+
for (i, c) in pattern.characters.enumerated() {
1111
skipTable[c] = patternLength - i - 1
1212
}
1313

14-
let p = pattern.endIndex.predecessor()
14+
let p = pattern.index(before: pattern.endIndex)
1515
let lastChar = pattern[p]
16-
var i = self.startIndex.advancedBy(patternLength - 1)
16+
var i = self.index(startIndex, offsetBy: patternLength - 1)
1717

1818
func backwards() -> String.Index? {
1919
var q = p
2020
var j = i
2121
while q > pattern.startIndex {
22-
j = j.predecessor()
23-
q = q.predecessor()
22+
j = index(before: j)
23+
q = index(before: q)
2424
if self[j] != pattern[q] { return nil }
2525
}
2626
return j
@@ -30,21 +30,19 @@ extension String {
3030
let c = self[i]
3131
if c == lastChar {
3232
if let k = backwards() { return k }
33-
i = i.successor()
33+
i = index(after: i)
3434
} else {
35-
i = i.advancedBy(skipTable[c] ?? patternLength)
35+
i = index(i, offsetBy: skipTable[c] ?? patternLength)
3636
}
3737
}
3838
return nil
3939
}
4040
}
4141

42-
43-
4442
// A few simple tests
4543

4644
let s = "Hello, World"
47-
s.indexOf("World") // 7
45+
s.indexOf(pattern: "World") // 7
4846

4947
let animals = "🐶🐔🐷🐮🐱"
50-
animals.indexOf("🐮") // 6
48+
animals.indexOf(pattern: "🐮") // 6

Boyer-Moore/BoyerMoore.playground/timeline.xctimeline

+15
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,20 @@
22
<Timeline
33
version = "3.0">
44
<TimelineItems>
5+
<LoggerValueHistoryTimelineItem
6+
documentLocation = "#CharacterRangeLen=1&amp;CharacterRangeLoc=345&amp;EndingColumnNumber=37&amp;EndingLineNumber=9&amp;StartingColumnNumber=9&amp;StartingLineNumber=9&amp;Timestamp=497585369.829471"
7+
selectedRepresentationIndex = "0"
8+
shouldTrackSuperviewWidth = "NO">
9+
</LoggerValueHistoryTimelineItem>
10+
<LoggerValueHistoryTimelineItem
11+
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=345&amp;EndingColumnNumber=26&amp;EndingLineNumber=9&amp;StartingColumnNumber=9&amp;StartingLineNumber=9&amp;Timestamp=497585369.82964"
12+
selectedRepresentationIndex = "0"
13+
shouldTrackSuperviewWidth = "NO">
14+
</LoggerValueHistoryTimelineItem>
15+
<LoggerValueHistoryTimelineItem
16+
documentLocation = "#CharacterRangeLen=1&amp;CharacterRangeLoc=345&amp;EndingColumnNumber=25&amp;EndingLineNumber=9&amp;StartingColumnNumber=9&amp;StartingLineNumber=9&amp;Timestamp=497585369.82978"
17+
selectedRepresentationIndex = "0"
18+
shouldTrackSuperviewWidth = "NO">
19+
</LoggerValueHistoryTimelineItem>
520
</TimelineItems>
621
</Timeline>

Boyer-Moore/README.markdown

+61-52
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ For example:
99
```swift
1010
// Input:
1111
let s = "Hello, World"
12-
s.indexOf("World")
12+
s.indexOf(pattern: "World")
1313

1414
// Output:
1515
<String.Index?> 7
1616

1717
// Input:
1818
let animals = "🐶🐔🐷🐮🐱"
19-
animals.indexOf("🐮")
19+
animals.indexOf(pattern: "🐮")
2020

2121
// Output:
2222
<String.Index?> 6
@@ -32,7 +32,7 @@ Here's how you could write it in Swift:
3232

3333
```swift
3434
extension String {
35-
func indexOf(pattern: String) -> String.Index? {
35+
func indexOf(pattern: String) -> String.Index? {
3636
// Cache the length of the search pattern because we're going to
3737
// use it a few times and it's expensive to calculate.
3838
let patternLength = pattern.characters.count
@@ -42,57 +42,58 @@ extension String {
4242
// Make the skip table. This table determines how far we skip ahead
4343
// when a character from the pattern is found.
4444
var skipTable = [Character: Int]()
45-
for (i, c) in pattern.characters.enumerate() {
46-
skipTable[c] = patternLength - i - 1
45+
for (i, c) in pattern.characters.enumerated() {
46+
skipTable[c] = patternLength - i - 1
4747
}
4848

4949
// This points at the last character in the pattern.
50-
let p = pattern.endIndex.predecessor()
50+
let p = index(before: pattern.endIndex)
5151
let lastChar = pattern[p]
5252

5353
// The pattern is scanned right-to-left, so skip ahead in the string by
5454
// the length of the pattern. (Minus 1 because startIndex already points
5555
// at the first character in the source string.)
56-
var i = self.startIndex.advancedBy(patternLength - 1)
56+
var i = index(self.startIndex, offsetBy: patternLength - 1)
5757

58-
// This is a helper function that steps backwards through both strings
58+
// This is a helper function that steps backwards through both strings
5959
// until we find a character that doesn’t match, or until we’ve reached
6060
// the beginning of the pattern.
6161
func backwards() -> String.Index? {
62-
var q = p
63-
var j = i
64-
while q > pattern.startIndex {
65-
j = j.predecessor()
66-
q = q.predecessor()
67-
if self[j] != pattern[q] { return nil }
68-
}
69-
return j
62+
var q = p
63+
var j = i
64+
while q > pattern.startIndex {
65+
j = index(before: j)
66+
q = index(before: q)
67+
if self[j] != pattern[q] { return nil }
68+
}
69+
return j
7070
}
7171

7272
// The main loop. Keep going until the end of the string is reached.
7373
while i < self.endIndex {
74-
let c = self[i]
75-
76-
// Does the current character match the last character from the pattern?
77-
if c == lastChar {
78-
79-
// There is a possible match. Do a brute-force search backwards.
80-
if let k = backwards() { return k }
81-
82-
// If no match, we can only safely skip one character ahead.
83-
i = i.successor()
84-
} else {
85-
// The characters are not equal, so skip ahead. The amount to skip is
86-
// determined by the skip table. If the character is not present in the
87-
// pattern, we can skip ahead by the full pattern length. However, if
88-
// the character *is* present in the pattern, there may be a match up
89-
// ahead and we can't skip as far.
90-
i = i.advancedBy(skipTable[c] ?? patternLength)
91-
}
74+
let c = self[i]
75+
76+
// Does the current character match the last character from the pattern?
77+
if c == lastChar {
78+
79+
// There is a possible match. Do a brute-force search backwards.
80+
if let k = backwards() { return k }
81+
82+
// If no match, we can only safely skip one character ahead.
83+
i = index(after: i)
84+
} else {
85+
// The characters are not equal, so skip ahead. The amount to skip is
86+
// determined by the skip table. If the character is not present in the
87+
// pattern, we can skip ahead by the full pattern length. However, if
88+
// the character *is* present in the pattern, there may be a match up
89+
// ahead and we can't skip as far.
90+
i = index(i, offsetBy: skipTable[c] ?? patternLength)
91+
}
9292
}
9393
return nil
94-
}
94+
}
9595
}
96+
9697
```
9798

9899
The algorithm works as follows. You line up the search pattern with the source string and see what character from the string matches the *last* character of the search pattern:
@@ -149,34 +150,42 @@ Here's an implementation of the Boyer-Moore-Horspool algorithm:
149150

150151
```swift
151152
extension String {
152-
public func indexOf(pattern: String) -> String.Index? {
153+
func indexOf(pattern: String) -> String.Index? {
153154
let patternLength = pattern.characters.count
154155
assert(patternLength > 0)
155156
assert(patternLength <= self.characters.count)
156157

157158
var skipTable = [Character: Int]()
158-
for (i, c) in pattern.characters.dropLast().enumerate() {
159-
skipTable[c] = patternLength - i - 1
159+
for (i, c) in pattern.characters.enumerated() {
160+
skipTable[c] = patternLength - i - 1
160161
}
161162

162-
var index = self.startIndex.advancedBy(patternLength - 1)
163-
164-
while index < self.endIndex {
165-
var i = index
166-
var p = pattern.endIndex.predecessor()
167-
168-
while self[i] == pattern[p] {
169-
if p == pattern.startIndex { return i }
170-
i = i.predecessor()
171-
p = p.predecessor()
172-
}
163+
let p = pattern.index(before: pattern.endIndex)
164+
let lastChar = pattern[p]
165+
var i = self.index(startIndex, offsetBy: patternLength - 1)
173166

174-
let advance = skipTable[self[index]] ?? patternLength
175-
index = index.advancedBy(advance)
167+
func backwards() -> String.Index? {
168+
var q = p
169+
var j = i
170+
while q > pattern.startIndex {
171+
j = index(before: j)
172+
q = index(before: q)
173+
if self[j] != pattern[q] { return nil }
174+
}
175+
return j
176176
}
177177

178+
while i < self.endIndex {
179+
let c = self[i]
180+
if c == lastChar {
181+
if let k = backwards() { return k }
182+
i = index(after: i)
183+
} else {
184+
i = index(i, offsetBy: skipTable[c] ?? patternLength)
185+
}
186+
}
178187
return nil
179-
}
188+
}
180189
}
181190
```
182191

Longest Common Subsequence/README.markdown

+2-2
Original file line numberDiff line numberDiff line change
@@ -152,15 +152,15 @@ func backtrack(_ matrix: [[Int]]) -> String {
152152
}
153153
}
154154

155-
return String(lcs.characters.reverse())
155+
return String(lcs.characters.reversed())
156156
}
157157
```
158158

159159
This backtracks from `matrix[n+1][m+1]` (bottom-right corner) to `matrix[1][1]` (top-right corner), looking for characters that are common to both strings. It adds those characters to a new string, `lcs`.
160160

161161
The `charInSequence` variable is an index into the string given by `self`. Initially this points to the last character of the string. Each time we decrement `i`, we also move back `charInSequence`. When the two characters are found to be equal, we add the character at `self[charInSequence]` to the new `lcs` string. (We can't just write `self[i]` because `i` may not map to the current position inside the Swift string.)
162162

163-
Due to backtracking, characters are added in reverse order, so at the end of the function we call `reverse()` to put the string in the right order. (Appending new characters to the end of the string and then reversing it once is faster than always inserting the characters at the front of the string.)
163+
Due to backtracking, characters are added in reverse order, so at the end of the function we call `reversed()` to put the string in the right order. (Appending new characters to the end of the string and then reversing it once is faster than always inserting the characters at the front of the string.)
164164

165165
## Putting it all together
166166

README.markdown

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ The goal of this project is to **explain how algorithms work**. The focus is on
1010

1111
All code is compatible with **Xcode 7.3** and **Swift 2.2**. We'll keep this updated with the latest version of Swift.
1212

13-
This is a work in progress. More algorithms will be added soon. :-)
13+
This is a work in progress. More algorithms will be added soon. :-)
1414

1515
:heart_eyes: **Suggestions and contributions are welcome!** :heart_eyes:
1616

@@ -26,7 +26,7 @@ This is a work in progress. More algorithms will be added soon. :-)
2626

2727
[How to contribute](How to Contribute.markdown). Report an issue to leave feedback, or submit a pull request.
2828

29-
[Under construction](Under Construction.markdown). Algorithms that are under construction.
29+
[Under construction](Under Construction.markdown). Algorithms that are under construction.
3030

3131
## Where to start?
3232

@@ -213,6 +213,7 @@ Other algorithm repositories:
213213
- [@lorentey](https://github.com/lorentey/). Production-quality Swift implementations of common algorithms and data structures.
214214
- [Rosetta Code](http://rosettacode.org). Implementations in pretty much any language you can think of.
215215
- [AlgorithmVisualizer](http://jasonpark.me/AlgorithmVisualizer/). Visualize algorithms on your browser.
216+
- [Swift Structures](https://github.com/waynewbishop/SwiftStructures) Data Structures with directions on how to use them [here](http://waynewbishop.com/swift)
216217

217218
## Credits
218219

Shell Sort/Tests/Tests.xcodeproj/project.pbxproj

+3
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
TargetAttributes = {
9292
7B2BBC7F1C779D720067B71D = {
9393
CreatedOnToolsVersion = 7.2;
94+
LastSwiftMigration = 0800;
9495
};
9596
};
9697
};
@@ -224,6 +225,7 @@
224225
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
225226
PRODUCT_BUNDLE_IDENTIFIER = swift.algorithm.club.Tests;
226227
PRODUCT_NAME = "$(TARGET_NAME)";
228+
SWIFT_VERSION = 3.0;
227229
};
228230
name = Debug;
229231
};
@@ -235,6 +237,7 @@
235237
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
236238
PRODUCT_BUNDLE_IDENTIFIER = swift.algorithm.club.Tests;
237239
PRODUCT_NAME = "$(TARGET_NAME)";
240+
SWIFT_VERSION = 3.0;
238241
};
239242
name = Release;
240243
};

Shell Sort/shellsort.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121
// SOFTWARE.
2222

23-
public func insertionSort(inout list: [Int], start: Int, gap: Int) {
24-
for i in (start + gap).stride(to: list.count, by: gap) {
23+
public func insertionSort(_ list: inout [Int], start: Int, gap: Int) {
24+
for i in stride(from: (start + gap), to: list.count, by: gap) {
2525
let currentValue = list[i]
2626
var pos = i
2727
while pos >= gap && list[pos - gap] > currentValue {
@@ -32,7 +32,7 @@ public func insertionSort(inout list: [Int], start: Int, gap: Int) {
3232
}
3333
}
3434

35-
public func shellSort(inout list: [Int]) {
35+
public func shellSort(_ list: inout [Int]) {
3636
var sublistCount = list.count / 2
3737
while sublistCount > 0 {
3838
for pos in 0..<sublistCount {

Topological Sort/Graph.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public class Graph: CustomStringConvertible {
77
adjacencyLists = [Node : [Node]]()
88
}
99

10-
public func addNode(value: Node) -> Node {
10+
public func addNode(_ value: Node) -> Node {
1111
adjacencyLists[value] = []
1212
return value
1313
}

0 commit comments

Comments
 (0)