Add examples on Swift 3.0.2 (#11)

* 01_binary_search Swift 3.0.2

* 01_binary_search Swift 3.0.2

* add Chapter 2 - 01_selection_sort Swift 3.0.2 example

* 01_binary_search cosmetic note updates Swift 3.0.2

* 03_recursion Swift 3.0.2 examples

* 04_quicksort Swift 3.0.2 examples

* fix typo on quicksort example. Swift 3.0.2

* add  05_hash_tables examples on Swift 3.0.2

* add 01_breadth-first_search Swift 3.0.2 example

* 01_breadth-first_search fixing typo Swift 3.0.2

* add 01_dijkstras_algorithm on Swift 3.0.2

* add 08_greedy_algorithms Swift 3.0.2 example

* 01_longest_common_subsequence Swift 3.0.2 example
This commit is contained in:
Anthony Marchenko
2017-03-16 02:05:38 +03:00
committed by Aditya Bhargava
parent 62ed616954
commit 12265a8c61
21 changed files with 467 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
import Foundation
// Note: If you arent familiar with Comparable, please check out Generics chapter in Swift book
func binarySearch <T: Comparable>(_ list: [T], item: T) -> Int? {
// low and high keep track of which part of the list you'll search in.
var low = 0
var high = list.count - 1
// While you haven't narrowed it down to one element ...
while low <= high {
//... check the middle element
let mid = low + (high - low) / 2
let guess = list[mid]
// Found the item.
if guess == item {
return mid
}
// The guess was too high.
if guess > item {
high = mid - 1
} else {
low = mid + 1
}
}
return nil
}
let myList = [1, 3, 5, 7, 9]
print(binarySearch(myList, item: 3) ?? "Not Found") // => 1
print(binarySearch(myList, item: -1) ?? "Not Found") // => Not Found

View File

@@ -0,0 +1,38 @@
import Foundation
// Finds the smallest value in an array
func findSmallestIndex <T: Comparable> (_ arr: [T]) -> Int {
// Stores the smallest value
var smallest = arr[0]
// We don't need any calculation if the array lenght is 1
if arr.count == 1 {
return 0
}
// Stores the index of the smallest value
var smallestIndex = 0
for i in 1...arr.count-1 {
if arr[i] < smallest {
smallest = arr[i]
smallestIndex = i
}
}
return smallestIndex
}
// Sort array
func selectionSort <T: Comparable> (arr: [T]) -> [T] {
var newArr: [T] = []
// We have to make mutableArray reference copy of original array, because Swift 3 doesn't allow to get var parameter
var mutableArr = arr
for _ in 0...mutableArr.count-1 {
//Finds the smallest element in the array and adds it to the new array
let smallestIndex = findSmallestIndex(mutableArr)
newArr.append(mutableArr[smallestIndex])
mutableArr.remove(at: smallestIndex)
}
return newArr
}
print(selectionSort(arr: [5, 3, 6, 2, 10])) // => [2, 3, 5, 6, 10]

View File

@@ -0,0 +1,16 @@
import Foundation
func countDown(i : Int) {
print(i)
// base case
if i <= 0 {
return
} else {
// recursive case
countDown(i: i-1)
}
}
countDown(i: 5)

View File

@@ -0,0 +1,18 @@
import Foundation
func greet2(name: String) {
print("how are you, \(name) ?")
}
func bye() {
print("ok bye!")
}
func greet(name: String ) {
print("hello, \(name)!")
greet2(name: name)
print("getting ready to say bye...")
bye()
}
greet(name: "adit")

View File

@@ -0,0 +1,12 @@
import Foundation
func fact(x: Int) -> Int {
if x == 1 {
return 1
} else {
return x*fact(x: x-1)
}
}
print(fact(x: 5)) // => 120

View File

@@ -0,0 +1,11 @@
import Foundation
func sum (_ arr: [Int]) -> Int {
var total = 0
for x in arr {
total += x
}
return total
}
print(sum([1, 2, 3, 4])) // => 10

View File

@@ -0,0 +1,12 @@
import Foundation
func sum(list : [Int]) -> Int {
if list.count == 0 {
return 0
}
var tempArray = list
tempArray.remove(at: 0)
return list[0] + sum(list: tempArray)
}
print(sum(list: [1, 2, 3, 4])) // => 10

View File

@@ -0,0 +1,12 @@
import Foundation
func count(list : [Int]) -> Int {
if list.count == 0 {
return 0
}
var tempArray = list
tempArray.remove(at: 0)
return 1 + count(list: tempArray)
}
print(count(list: [1, 2, 3, 4])) // => 4

View File

@@ -0,0 +1,13 @@
import Foundation
func max(list : [Int]) -> Int {
if list.count == 2 {
return (list[0] > list[1]) ? list[0] : list[1]
}
var tempArray = list
tempArray.remove(at: 0)
let subMax = max(list: tempArray)
return (list[0] > subMax) ? list[0] : subMax
}
print(max(list: [1, 5, 10, 25, 16, 1])) // => 25

View File

@@ -0,0 +1,21 @@
import Foundation
//The following implementation of quick sort is little more classic than described in the book, but we have two use this one because of some slice feature limitation with array on Swift 3. Main concept is the same
func quicksort <T : Comparable> (_ array : [T]) -> [T] {
if (array.count < 2) {
// base case, arrays with 0 or 1 element are already "sorted"
return array
} else {
// recursive case
let pivot = array[0]
// sub-array of all the elements less than the pivot
let less = array.filter { $0 < pivot }
// sub-array of all the elements equal to the pivot
let equal = array.filter { $0 == pivot }
// sub-array of all the elements greater than the pivot
let greater = array.filter { $0 > pivot }
return quicksort(less) + equal + quicksort(greater)
}
}
print(quicksort([1, 5, 10, 25, 16, 1])) // => [1, 1, 5, 10, 16, 25]

View File

@@ -0,0 +1,18 @@
import Foundation
var book = [String: Double]()
// an apple costs 67 cents
book["apple"] = 0.67
//# milk costs $1.49
book["milk"] = 1.49
book["avacado"] = 1.49
print(book) // => ["avacado": 1.49, "apple": 0.67000000000000004, "milk": 1.49]
// Qustion: Why is "apple" is 0.67000000000000004 intsted of 0.67?
// Answer: Double cannot store the value 0.67 exactly. Swift uses (like many other languages) binary floating point numbers according to the IEEE 754 standard.
// This topic is not related with Algorithms, but you can play with .description and .debugDescription for making workarrounds
print(book["apple"]?.description ?? "Not exist") // => 0.67
print(book["apple"]?.debugDescription ?? "Not exist") // => 0.67000000000000004

View File

@@ -0,0 +1,18 @@
import Foundation
var voter = [String : Bool]()
func checkVoter(_ name : String) {
if voter[name] != nil {
print("kick them out!")
} else {
voter[name] = true
print("let them vote!")
}
}
checkVoter("tom")
checkVoter("mike")
checkVoter("mike")

View File

@@ -0,0 +1,93 @@
import Foundation
// As I can see Swift doesn't have Queue default implementation, so we have to use custom on, Degue structure from Swift Algorithm Club
// https://github.com/raywenderlich/swift-algorithm-club/tree/master/Deque
public struct Deque<T> {
private var array = [T]()
public var isEmpty: Bool {
return array.isEmpty
}
public var count: Int {
return array.count
}
public mutating func enqueue(_ element: T) {
array.append(element)
}
public mutating func enqueueFront(_ element: T) {
array.insert(element, at: 0)
}
public mutating func dequeue() -> T? {
if isEmpty {
return nil
} else {
return array.removeFirst()
}
}
public mutating func dequeueBack() -> T? {
if isEmpty {
return nil
} else {
return array.removeLast()
}
}
public func peekFront() -> T? {
return array.first
}
public func peekBack() -> T? {
return array.last
}
}
func persionIsSeller(name: String) -> Bool {
return name.characters.last == "m"
}
var graph = [String : [String]]()
graph["you"] = ["alice", "bob", "claire"]
graph["bob"] = ["anuj", "peggy"]
graph["alice"] = ["peggy"]
graph["claire"] = ["thom", "jonny"]
graph["anuj"] = []
graph["peggy"] = []
graph["thom"] = []
graph["jonny"] = []
func search(name: String) -> Bool {
var searchQueue = Deque<String>()
//Swift Note: Our custom Deque doesn't have possibility to add new element as array so we have to add elements one by one (insted of +=graph["person"] in the book example)
for string in graph[name]! {
searchQueue.enqueue(string)
}
// This array is how you keep track of which people you've searched before.
var searched = [String]()
while !searchQueue.isEmpty {
let person = searchQueue.dequeue()
// Only search this person if you haven't already searched them
if !searched.contains(person!) {
if persionIsSeller(name: person!) {
print("\(person!) is a mango seller!")
return true
} else {
for string in graph[person!]! {
searchQueue.enqueue(string)
}
// Marks this person as searched
searched.append(person!)
}
}
}
return false
}
if search(name: "you") == false {
print("Mango seller Not Found!")
} // => thom is a mango seller!

View File

@@ -0,0 +1,79 @@
import Foundation
// the graph
var graph = [String : [String: Double]] ()
graph["start"] = [String: Double]()
graph["start"]?["a"] = 6
graph["start"]?["b"] = 2
graph["a"] = [String: Double]()
graph["a"]?["fin"] = 1
graph["b"] = [String: Double]()
graph["b"]?["a"] = 3
graph["b"]?["fin"] = 5
graph["fin"] = [String: Double]()
// the costs table
let infinity = Double.infinity
var costs = [String: Double]()
costs["a"] = 6
costs["b"] = 2
costs["fin"] = infinity
// the parents table
var parents = [String: String]()
parents["a"] = "start"
parents["b"] = "start"
parents["fin"] = nil
var processed = [String]()
func findLowestCostNode(costs: [String: Double]) -> [String: Double] {
var lowestCost = Double.infinity
var lowestCostNode = [String: Double]()
// Go through each node.
for node in costs {
let cost = node.value
// If it's the lowest cost so far and hasn't been processed yet...
if (cost < lowestCost) && !processed.contains(node.key) {
// ... set it as the new lowest-cost node.
lowestCost = cost
lowestCostNode = [node.key : node.value]
}
}
return lowestCostNode
}
// Find the lowest-cost node that you haven't processed yet.
var node = findLowestCostNode(costs: costs)
// If you've processed all the nodes, this while loop is done.
while !node.isEmpty {
// Swift Note: Unfortunately there are some limits for working with Dictionary inside Dictionary, so we have to use temp "nodeFirstKey" variable as workaround
var nodeFirstKey = node.first?.key
var cost = costs[nodeFirstKey!]
// Go through all the neighbors of this node.
var neighbors = graph[nodeFirstKey!]
for n in (neighbors?.keys)! {
var newCost = cost! + (neighbors?[n])!
// If it's cheaper to get to this neighbor by going through this node...
if costs[n]! > newCost {
// ... update the cost for this node.
costs[n] = newCost
// This node becomes the new parent for this neighbor.
parents[n] = nodeFirstKey
}
}
// Mark the node as processed.
processed.append(nodeFirstKey!)
// Find the next node to process, and loop.
node = findLowestCostNode(costs: costs)
}
print("Cost from the start to each node:")
print(costs) // -> ["b": 2.0, "fin": 6.0, "a": 5.0]

View File

@@ -0,0 +1,35 @@
import Foundation
// You pass an array in, and it gets converted to a set.
var statesNeeded : Set = ["mt", "wa", "or", "id", "nv", "ut", "ca", "az"]
var stations = [String: Set<String>]()
stations["kone"] = ["id", "nv", "ut"]
stations["ktwo"] = ["wa", "id", "mt"]
stations["kthree"] = ["or", "nv", "ca"]
stations["kfour"] = ["nv", "ut"]
stations["kfive"] = ["ca", "az"]
var finalStations = Set<String>();
while !statesNeeded.isEmpty {
var bestStation = String()
var statesCovered = Set<String>()
for station in stations {
var covered = statesNeeded.intersection(station.value)
if covered.count > statesCovered.count {
bestStation = station.key
statesCovered = covered
}
statesNeeded = statesNeeded.subtracting(statesCovered)
//Swift note: We should avoid adding empty station to Set
if !bestStation.isEmpty {
finalStations.insert(bestStation)
}
}
}
print(finalStations) // -> ["kone", "kfive", "ktwo", "kthree"]

View File

@@ -0,0 +1,40 @@
import Foundation
if wordA[i] == wordB[j] {
// The letters match
cell[i][j] = cell[i-1][j-1] + 1
} else {
// The letters don't match.
cell[i][j] = max(cell[i-1][j], cell[i][j-1])
}
/* Working example for "play" with
var wordA = "fish"
var wordB = "hish"
var cell : [[Int]] = Array(repeating: Array(repeating: 0, count: wordA.characters.count), count: wordB.characters.count)
let wordAArray = wordA.characters.map { String($0) }
let wordBArray = wordB.characters.map { String($0) }
for i in 0...wordA.characters.count-1 {
for j in 0...wordB.characters.count-1 {
// The letters match
if wordAArray[i] == wordBArray[j] {
if i > 0 && j > 0 {
cell[i][j] = cell[i-1][j-1] + 1
} else {
cell[i][j] = 1
}
} else {
// The letters don't match.
if i > 0 && j > 0 {
cell[i][j] = max(cell[i-1][j], cell[i][j-1])
} else {
cell[i][j] = 0
}
}
}
}
*/

BIN
images/.DS_Store vendored

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.