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:
committed by
Aditya Bhargava
parent
62ed616954
commit
12265a8c61
31
01_introduction_to_algorithms/swift/01_binary_search.swift
Normal file
31
01_introduction_to_algorithms/swift/01_binary_search.swift
Normal file
@@ -0,0 +1,31 @@
|
||||
import Foundation
|
||||
|
||||
// Note: If you aren’t 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
|
||||
|
||||
38
02_selection_sort/swift/01_selection_sort.swift
Normal file
38
02_selection_sort/swift/01_selection_sort.swift
Normal 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]
|
||||
|
||||
|
||||
16
03_recursion/swift/01_countdown.swift
Normal file
16
03_recursion/swift/01_countdown.swift
Normal 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)
|
||||
|
||||
|
||||
18
03_recursion/swift/02_greet.swift
Normal file
18
03_recursion/swift/02_greet.swift
Normal 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")
|
||||
12
03_recursion/swift/03_factorial.swift
Normal file
12
03_recursion/swift/03_factorial.swift
Normal 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
|
||||
11
04_quicksort/swift/01_loop_sum.swift
Normal file
11
04_quicksort/swift/01_loop_sum.swift
Normal 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
|
||||
12
04_quicksort/swift/02_recursive_sum.swift
Normal file
12
04_quicksort/swift/02_recursive_sum.swift
Normal 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
|
||||
12
04_quicksort/swift/03_recursive_count.swift
Normal file
12
04_quicksort/swift/03_recursive_count.swift
Normal 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
|
||||
13
04_quicksort/swift/04_recursive_max.swift
Normal file
13
04_quicksort/swift/04_recursive_max.swift
Normal 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
|
||||
21
04_quicksort/swift/05_quicksort.swift
Normal file
21
04_quicksort/swift/05_quicksort.swift
Normal 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]
|
||||
18
05_hash_tables/swift/01_price_of_groceries.swift
Normal file
18
05_hash_tables/swift/01_price_of_groceries.swift
Normal 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
|
||||
|
||||
|
||||
|
||||
18
05_hash_tables/swift/02_check_voter.swift
Normal file
18
05_hash_tables/swift/02_check_voter.swift
Normal 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")
|
||||
|
||||
|
||||
93
06_breadth-first_search/swift/01_breadth-first_search.swift
Normal file
93
06_breadth-first_search/swift/01_breadth-first_search.swift
Normal 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!
|
||||
79
07_dijkstras_algorithm/swift/01_dijkstras_algorithm.swift
Normal file
79
07_dijkstras_algorithm/swift/01_dijkstras_algorithm.swift
Normal 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]
|
||||
|
||||
35
08_greedy_algorithms/swift/01_set_covering.swift
Normal file
35
08_greedy_algorithms/swift/01_set_covering.swift
Normal 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"]
|
||||
|
||||
|
||||
@@ -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
BIN
images/.DS_Store
vendored
Binary file not shown.
BIN
images/01_introduction_to_algorithms/.DS_Store
vendored
BIN
images/01_introduction_to_algorithms/.DS_Store
vendored
Binary file not shown.
BIN
images/02_selection_sort/.DS_Store
vendored
BIN
images/02_selection_sort/.DS_Store
vendored
Binary file not shown.
BIN
images/08_greedy_algorithms/.DS_Store
vendored
BIN
images/08_greedy_algorithms/.DS_Store
vendored
Binary file not shown.
BIN
images/11_where_to_go_next/.DS_Store
vendored
BIN
images/11_where_to_go_next/.DS_Store
vendored
Binary file not shown.
Reference in New Issue
Block a user