Skip to content

Commit

Permalink
Merge pull request #1 from raywenderlich/master
Browse files Browse the repository at this point in the history
merge from orignal
  • Loading branch information
KeithMorning authored Apr 25, 2018
2 parents e0c0200 + b83ef3b commit 087daa9
Show file tree
Hide file tree
Showing 75 changed files with 2,831 additions and 913 deletions.
4 changes: 2 additions & 2 deletions Big-O Notation.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ Below are some examples for each category of performance:
The most trivial example of function that takes O(n!) time is given below.

```swift
func nFacFunc(n: Int) {
func nFactFunc(n: Int) {
for i in stride(from: 0, to: n, by: 1) {
nFactFunc(n - 1)
nFactFunc(n: n - 1)
}
}
```
Expand Down
2 changes: 1 addition & 1 deletion Binary Search Tree/README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ As an exercise, see if you can implement filter and reduce.
We can make the code more readable by defining some helper functions.

```swift
private func reconnectParentToNode(node: BinarySearchTree?) {
private func reconnectParentTo(node: BinarySearchTree?) {
if let parent = parent {
if isLeftChild {
parent.left = node
Expand Down
6 changes: 3 additions & 3 deletions Binary Search/README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ Goal: Quickly find an element in an array.

Let's say you have an array of numbers and you want to determine whether a specific number is in that array, and if so, at which index.

In most cases, Swift's `indexOf()` function is good enough for that:
In most cases, Swift's `Collection.index(of:)` function is good enough for that:

```swift
let numbers = [11, 59, 3, 2, 53, 17, 31, 7, 19, 67, 47, 13, 37, 61, 29, 43, 5, 41, 23]

numbers.indexOf(43) // returns 15
numbers.index(of: 43) // returns 15
```

The built-in `indexOf()` function performs a [linear search](../Linear%20Search/). In code that looks something like this:
The built-in `Collection.index(of:)` function performs a [linear search](../Linear%20Search/). In code that looks something like this:

```swift
func linearSearch<T: Equatable>(_ a: [T], _ key: T) -> Int? {
Expand Down
2 changes: 1 addition & 1 deletion Brute-Force String Search/README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@ extension String {

This looks at each character in the source string in turn. If the character equals the first character of the search pattern, then the inner loop checks whether the rest of the pattern matches. If no match is found, the outer loop continues where it left off. This repeats until a complete match is found or the end of the source string is reached.

The brute-force approach works OK, but it's not very efficient (or pretty). It should work fine on small strings, though. For a smarter algorithm that works better with large chunks of text, check out [Boyer-Moore](../Boyer-Moore/) string search.
The brute-force approach works OK, but it's not very efficient (or pretty). It should work fine on small strings, though. For a smarter algorithm that works better with large chunks of text, check out [Boyer-Moore](../Boyer-Moore-Horspool) string search.

*Written for Swift Algorithm Club by Matthijs Hollemans*
20 changes: 10 additions & 10 deletions Combinatorics/README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,17 @@ Here's a recursive algorithm by Niklaus Wirth:

```swift
func permuteWirth<T>(_ a: [T], _ n: Int) {
if n == 0 {
print(a) // display the current permutation
} else {
var a = a
permuteWirth(a, n - 1)
for i in 0..<n {
swap(&a[i], &a[n])
permuteWirth(a, n - 1)
swap(&a[i], &a[n])
if n == 0 {
print(a) // display the current permutation
} else {
var a = a
permuteWirth(a, n - 1)
for i in 0..<n {
a.swapAt(i, n)
permuteWirth(a, n - 1)
a.swapAt(i, n)
}
}
}
}
```

Expand Down
6 changes: 3 additions & 3 deletions Convex Hull/Convex Hull.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@
};
8E6D68B51E59989400161780 = {
CreatedOnToolsVersion = 8.2.1;
DevelopmentTeam = 7C4LVS3ZVC;
DevelopmentTeam = 4SQG5NJNPF;
ProvisioningStyle = Automatic;
};
};
Expand Down Expand Up @@ -384,7 +384,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = 7C4LVS3ZVC;
DEVELOPMENT_TEAM = 4SQG5NJNPF;
INFOPLIST_FILE = "Convex Hull/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "workmoose.Convex-Hull";
Expand All @@ -397,7 +397,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = 7C4LVS3ZVC;
DEVELOPMENT_TEAM = 4SQG5NJNPF;
INFOPLIST_FILE = "Convex Hull/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "workmoose.Convex-Hull";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
12 changes: 2 additions & 10 deletions Convex Hull/Convex Hull/View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,20 @@ import UIKit
class View: UIView {

let MAX_POINTS = 100

var points = [CGPoint]()

var convexHull = [CGPoint]()

override init(frame: CGRect) {
super.init(frame: frame)

// last checked with Xcode 9.0b4
#if swift(>=4.0)
print("Hello, Swift 4!")
#endif

generatePoints()
generateRandomPoints()
quickHull(points: points)
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

func generatePoints() {
func generateRandomPoints() {
for _ in 0..<MAX_POINTS {
let offset: CGFloat = 50
let xrand = CGFloat(arc4random()) / CGFloat(UINT32_MAX) * (self.frame.width - offset) + 0.5 * offset
Expand Down
18 changes: 14 additions & 4 deletions Convex Hull/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
# Convex Hull

There are multiple Convex Hull algorithms. This particular implementation uses the Quickhull algorithm.
Given a group of points on a plane. The Convex Hull algorithm calculates the shape (made up from the points itself) containing all these points. It can also be used on a collection of points of different dimensions. This implementation however covers points on a plane. It essentially calculates the lines between points which together contain all points. In comparing different solutions to this problem we can describe each algorithm in terms of it's big-O time complexity.

Given a group of points on a plane. The Convex Hull algorithm calculates the shape (made up from the points itself) containing all these points. It can also be used on a collection of points of different dimensions. This implementation however covers points on a plane. It essentially calculates the lines between points which together contain all points.
There are multiple Convex Hull algorithms but this solution is called Quickhull, is comes from the work of both W. Eddy in 1977 and also separately A. Bykat in 1978, this algorithm has an expected time complexity of O(n log n), but it's worst-case time-complexity can be O(n^2) . With average conditions the algorithm has ok efficiency, but it's time-complexity can start to head become more exponential in cases of high symmetry or where there are points lying on the circumference of a circle for example.

## Quickhull

The quickhull algorithm works as follows:
The algorithm takes an input of a collection of points. These points should be ordered on their x-coordinate value. We pick the two points A and B with the smallest(A) and the largest(B) x-coordinate. These of course have to be part of the hull. Imagine a line from point A to point B. All points to the right of this line are grouped in an array S1. Imagine now a line from point B to point A. (this is of course the same line as before just with opposite direction) Again all points to the right of this line are grouped in an array, S2 this time.
We now define the following recursive function:

- The algorithm takes an input of a collection of points. These points should be ordered on their x-coordinate value.
- We first find the two points A and B with the minimum(A) and the maximum(B) x-coordinates (as these will obviously be part of the hull).
- Use the line formed by the two points to divide the set in two subsets of points, which will be processed recursively.
- Determine the point, on one side of the line, with the maximum distance from the line. The two points found before along with this one form a triangle.
- The points lying inside of that triangle cannot be part of the convex hull and can therefore be ignored in the next steps.
- Repeat the previous two steps on the two lines formed by the triangle (not the initial line).
- Keep on doing so on until no more points are left, the recursion has come to an end and the points selected constitute the convex hull.


Our functioni will have the following defininition:

`findHull(points: [CGPoint], p1: CGPoint, p2: CGPoint)`

Expand All @@ -18,6 +27,7 @@ findHull(S2, B, A)
```

What this function does is the following:

1. If `points` is empty we return as there are no points to the right of our line to add to our hull.
2. Draw a line from `p1` to `p2`.
3. Find the point in `points` that is furthest away from this line. (`maxPoint`)
Expand Down
2 changes: 1 addition & 1 deletion DiningPhilosophers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Based on the Chandy and Misra's analysis, a system of preference levels is deriv

# Swift implementation

This Swift 3.0 implementation of the Chandy/Misra solution is based on the GCD and Semaphore tecnique that can be built on both macOS and Linux.
This Swift 3.0 implementation of the Chandy/Misra solution is based on the GCD and Semaphore technique that can be built on both macOS and Linux.

The code is based on a ForkPair struct used for holding an array of DispatchSemaphore and a Philosopher struct for associate a couple of forks to each Philosopher.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//: Playground - noun: a place where people can play

func printTree(_ root: BinaryNode<String>?) {
guard let root = root else {
return
}

let leftVal = root.left == nil ? "nil" : root.left!.val
let rightVal = root.right == nil ? "nil" : root.right!.val

print("val: \(root.val) left: \(leftVal) right: \(rightVal)")

printTree(root.left)
printTree(root.right)
}

let coder = BinaryNodeCoder<String>()

let node1 = BinaryNode("a")
let node2 = BinaryNode("b")
let node3 = BinaryNode("c")
let node4 = BinaryNode("d")
let node5 = BinaryNode("e")

node1.left = node2
node1.right = node3
node3.left = node4
node3.right = node5

let encodeStr = try coder.encode(node1)
print(encodeStr)
// "a b # # c d # # e # #"


let root: BinaryNode<String> = coder.decode(from: encodeStr)!
print("Tree:")
printTree(root)
/*
Tree:
val: a left: b right: c
val: b left: nil right: nil
val: c left: d right: e
val: d left: nil right: nil
val: e left: nil right: nil
*/

Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//
// EncodeAndDecodeTree.swift
//
//
// Created by Kai Chen on 19/07/2017.
//
//

import Foundation

protocol BinaryNodeEncoder {
func encode<T>(_ node: BinaryNode<T>?) throws -> String
}

protocol BinaryNodeDecoder {
func decode<T>(from string: String) -> BinaryNode<T>?
}

public class BinaryNodeCoder<T: Comparable>: BinaryNodeEncoder, BinaryNodeDecoder {

// MARK: Private

private let separator: Character = ","
private let nilNode = "X"

private func decode<T>(from array: inout [String]) -> BinaryNode<T>? {
guard !array.isEmpty else {
return nil
}

let value = array.removeLast()

guard value != nilNode, let val = value as? T else {
return nil
}

let node = BinaryNode<T>(val)
node.left = decode(from: &array)
node.right = decode(from: &array)

return node
}

// MARK: Public

public init() {}

public func encode<T>(_ node: BinaryNode<T>?) throws -> String {
var str = ""
node?.preOrderTraversal { data in
if let data = data {
let string = String(describing: data)
str.append(string)
} else {
str.append(nilNode)
}
str.append(separator)
}

return str
}

public func decode<T>(from string: String) -> BinaryNode<T>? {
var components = string.split(separator: separator).reversed().map(String.init)
return decode(from: &components)
}
}

public class BinaryNode<Element: Comparable> {
public var val: Element
public var left: BinaryNode?
public var right: BinaryNode?

public init(_ val: Element, left: BinaryNode? = nil, right: BinaryNode? = nil) {
self.val = val
self.left = left
self.right = right
}

public func preOrderTraversal(visit: (Element?) throws -> ()) rethrows {
try visit(val)

if let left = left {
try left.preOrderTraversal(visit: visit)
} else {
try visit(nil)
}

if let right = right {
try right.preOrderTraversal(visit: visit)
} else {
try visit(nil)
}
}
}
Loading

0 comments on commit 087daa9

Please sign in to comment.