diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..37b1d86 Binary files /dev/null and b/.DS_Store differ diff --git a/HWFrom1-17-16(Lists and Sorts).playground/Contents.swift b/HWFrom1-17-16(Lists and Sorts).playground/Contents.swift index 13cc14e..b26d14b 100644 --- a/HWFrom1-17-16(Lists and Sorts).playground/Contents.swift +++ b/HWFrom1-17-16(Lists and Sorts).playground/Contents.swift @@ -11,16 +11,278 @@ Work on your solutions here. Link: https://docs.google.com/document/d/1INvOynuggw69yLRNg3y-TPwBiYb3lQZQiFUOxZKBwsY/edit#heading=h.za36ai6n5fth -1) +1) Given a partially filled in Sudoku board and a set of coordinates in that board pointing to an empty square, write a function that returns a list containing all numbers that the empty square could be. +Input: sudokuBoard:[[Int?]]. (Each location on the board will be either be an Int from 1-9 or nil(empty cell)) +row: Int +col: Int +func getValidNumbers(sudokuBoard:[[Int?]], row:Int, col:Int) -> [Int] { +return [Int]() +} -2) +Sample input: ,4,4 +sample output: [1,3,4,5,6,8] +*/ +/* + +func getValidNumbers(sudokuBoard:[[Int?]], row:Int, col:Int)->[Int] { + var availableNumbersMap = Array(count: 9, repeatedValue: true) + // check rows + for i in (0..<9) { + if( i != row && sudokuBoard[i][col] != nil) { + let usedNumber = sudokuBoard[i][col]! + availableNumbersMap[usedNumber - 1] = false + } + } + + //check cols + for i in (0..<9) { + if( i != row && sudokuBoard[row][i] != nil) { + let usedNumber = sudokuBoard[row][i]! + availableNumbersMap[usedNumber - 1] = false + } + } + + //check 3x3 box + let rowMultiplier = row/3 // taking advantage of integer division + let rowOffset = rowMultiplier*3 // ex: 8/3 = 2 + let colMultiplier = col/3 + let colOffset = colMultiplier*3 + for i in (0..<3) { + for j in (0..<3) { + if rowOffset+i != row && colOffset+j != col && sudokuBoard[rowOffset+i][colOffset+j] != nil { + let usedNumber = sudokuBoard[rowOffset+i][colOffset+i]! + availableNumbersMap[usedNumber - 1] = false + } + } + } + + // convert availableNumbers to an array of Ints + var availableNumbers = [Int]() + for i in (0.. [Int] { + var valid: Set = [1, 2, 3, 4, 5, 6, 7, 8, 9] + + for c in 0..(valid) + +} + let sampleInput: [[Int?]] = [ + [5, 0, 8, 0, 7, 3, 1, 9, 0], + [9, 0, 0, 6, 0, 0, 4, 0, 8], + [0, 0, 0, 9, 0, 8, 0, 3, 5], + [0, 7, 0, 0, 0, 0, 0, 6, 0], + [0, 0, 2, 0, 0, 0, 9, 0, 0], + [0, 1, 0, 0, 0, 0, 0, 8, 0], + [1, 9, 0, 3, 0, 6, 0, 0, 0], + [2, 0, 3, 0, 0, 7, 0, 0, 9], + [0, 8, 7, 1, 9, 0, 3, 0, 4]] + + getValidNumbers(sampleInput, row: 0, col: 1) + + */ + + //Method 1 + // loop through the row, the column and the box, create a set. + // call .subtract to get the values + + //Method 2 + // loop through the row and create an array with existing integers on the row + // loop through the column, add the integers on the column to the array if they are not there + // loop through the box, add the integers on the box to the array if they are not there + // compare the array with the array [1, 2, 3, 4, 5, 6, 7, 8, 9], the missing integest will be the numbers that the empty square could be. + + +// var sudokuBoard = [ +// [5, 0, 8, 0, 7, 3, 1, 9, 0], +// [9, 0, 0, 6, 0, 0, 4, 0, 8], +// [0, 0, 0, 9, 0, 8, 0, 3, 5], +// [0, 7, 0, 0, 0, 0, 0, 6, 0], +// [0, 0, 2, 0, 0, 0, 9, 0, 0], +// [0, 1, 0, 0, 0, 0, 0, 8, 0], +// [1, 9, 0, 3, 0, 6, 0, 0, 0], +// [2, 0, 3, 0, 0, 7, 0, 0, 9], +// [0, 8, 7, 1, 9, 0, 3, 0, 4]] +// + + + + + + +/* + +2) rotate a matrix by ninety degrees +Input: matrix:[[Int]] +Output: matrix: [[Int]] + +Sample Input: [[1,2,3,4], +[5,6,7,8], +[9,0,1,2], +[3,4,5,6]] + +Sample Output: [ [3,9,5,1], +[4,0,6,2], +[5,1,7,3], +[6,2,8,4] ] + + +*/ + +// O(N*M) space +// Extra: think of a way to do the rotation inplace +// meaning don't use any extra arrays. +func rotateMatrix(mat:[[Int]]) -> [[Int]] { + let newRowCount = mat[0].count // new number of rows will be the same as + let newColCount = mat.count // the old number of cols. vice versa for cols + var newMat = Array(count: newRowCount, repeatedValue: Array(count: newColCount, repeatedValue: 0)) + for i in (0.. [[Int]] { + let n = matrix.count + + var result: [[Int]] = [] + + for _ in 0.. 0, n - 1 + // r, c -> r, n - c -1 + + // 0, n - 1 -> n - 1, n - 1 + // r, c -> n - r - 1, c + + // n - 1, n -1 -> n - 1, 0 + // r, c -> n + + +//The old matrix [arr1[0], arr1[1], arr1[2],...arr1[n-1], +// arr2[0], arr2[1], arr2[2],...arr2[n-1], +// arr3[0], arr3[1], arr3[2],...arr3[n-1], +// ... +// arrN[0], arrN[1], arrN[2],...arrN[n-1]] + +// The new matrix will be [arrN[0],...,arr3[0],arr2[0], arr1[0], +// arrN[1],...,arr3[1],arr2[1], arr1[1], +// arrN[2],...,arr3[2],arr2[2], arr1[2], +// ... +// arrN[n-1],...,arr3[n-1],arr2[n-1], arr1[n-1]] + + +/* + +3)Design an optimal algorithm for sorting four elements A, B, C, and D. By optimal, I mean one that sorts using the minimum number of comparisons. Hint: you may want to start by putting the first two items in order and the last two items in order... that takes two comparisons. How many more comparisons do you need to find the minimum element? The maximum? Once you’ve found the min and max, what if any additional comparisons are needed? + + + + +<<<<<<< HEAD +func mySort(values: [Int]) -> [Int] { + var left = values[0...1] + if left[0] > left[1] { + let t = left[0] + left[0] = left[1] + left[1] = t + } + var right = values[2...4] + if right[0] > right[1] { + let t = right[0] + right[0] = right[1] + right[1] = t + } + + return + +} +*/ +//put A and B in order, and put C and D in order +//find the minAB and maxAB for A and B +//find the minCD and maxCD for C and D +//compare minAB and minCD to get min, compare maxAB and maxCD to get max +// +======= */ +>>>>>>> df0dff8f1511200af5eae06e949d0d5f90c95b74 diff --git a/HWFrom1-24(Recursion).playground/Contents.swift b/HWFrom1-24(Recursion).playground/Contents.swift index 1c44504..cd30e9d 100644 --- a/HWFrom1-24(Recursion).playground/Contents.swift +++ b/HWFrom1-24(Recursion).playground/Contents.swift @@ -3,6 +3,179 @@ Homework link: https://docs.google.com/document/d/1INvOynuggw69yLRNg3y-TPwBiYb3lQZQiFUOxZKBwsY/edit#heading=h.za36ai6n5fth +<<<<<<< HEAD +*/ + +//Question 1 + +//Write an iterative (not recursive) fibonacci function that calculates the nth fibonacci number. How does its performance compare with the non-memoized recursive one (see Appendix A below), based on the number of iterations that Swift says it takes in the right margin? +//Appendix A: Recursive Fibonacci from class (non-memoized) +//func fib(n: Int) -> Int { +// print("X") +// if (n == 0 || n == 1) { +// return 1 +// } +// return fib(n - 1) + fib(n - 2) +//} + +//memorized fib +var cache = [Int: Int]() +cache[0] = 1 +cache[1] = 1 + +func fibm(n: Int) -> Int { + print("X") + if cache[n] != nil { + return cache[n]! + } + let value = fibm(n - 1) + fibm(n - 2) + cache[n] = value + return value +} +(0...5).map { i in fibm(i) } +//fibm(15) + + +//non-memorized fib +func fib(n: Int) -> Int { + print("X") + if (n == 0 || n == 1) { + return 1 + } + return fib(n - 1) + fib(n - 2) + +} +(0...5).map { i in fib(i) } + +//fib(15) + +//interative fib + +func fibonacci(n: Int) -> Int { +// Some temporary variables. +var a = 0 +var b = 1 +// Add up numbers to the desired iteration. +for _ in 0.. Int { + let stepCount = Int(arc4random_uniform(3)) - 1 + stepNum += stepCount; + switch(stepCount) { + case -1: print("Ouch \(stepNum)") + case 1: print("Yay \(stepNum)") + default: print("Beep \(stepNum)") + } + return stepCount +} + +func stepUp() { + switch tryStep() { + case 1: + return + case -1: + stepUp() + stepUp() + default: + stepUp() + } +} + + + +/* +var stepNum = 0 +func tryStep() -> Bool { + let success = Int(arc4random_uniform(2)) > 0 + if (success) { + stepNum++ + print("Yay! \(stepNum)") + } else { + stepNum--; + print("Ow! \(stepNum)") + } + return success +} +​ +func stepUp() { + if tryStep() { + // We’re done! + return + } + // Now we’re two steps below where we want to be :-( + stepUp() + stepUp() +} +*/ + + + +//Question 3 +//Using the code in Appendix C as a starting point, create a Swift command line project to find files on your computer by name. Your solution should use recursion. Your method should return “NOT FOUND” if it couldn’t find the file, otherwise it should return the full path to that file. + +//You can’t use a playground for this because they don’t have filesystem access for some reason. Instead, in XCode, go to File > New > Project, select “Application” under “OS X” in the sidebar, then select “Command Line Tool”; on the next screen, choose “Swift” as the language. + +//Appendix C: File searching +import Foundation + +func findFile(name: String, atPath: String) -> String { + let fileManager = NSFileManager.defaultManager() + let contents = + try! fileManager.contentsOfDirectoryAtPath(atPath) + for fileOrDir in contents { + var isDir = ObjCBool(false); + let fullPath = atPath + "/" + fileOrDir + let exists = fileManager.fileExistsAtPath(fullPath, isDirectory: &isDir) + if exists && Bool(isDir) { + // YOUR CODE HERE +// print("DIR: " + fileOrDir) + let result = findFile(name, atPath: fullPath) + if result != "NOT FOUND" { + return result + } + } else if exists { + // YOUR CODE HERE +// print("FILE: " + fileOrDir) + if fileOrDir == name { + return fullPath + } + } else { + print("NEITHER: " + fileOrDir) + } + } + return "NOT FOUND" +} + +//print(findFile("awesome-idea.txt", atPath: "/Users/C4Q/Documents")) + + +======= */ @@ -22,4 +195,5 @@ Homework link: https://docs.google.com/document/d/1INvOynuggw69yLRNg3y-TPwBiYb3l -//Question 3 \ No newline at end of file +//Question 3 +>>>>>>> 38eac0e09074171b6ee04fb720bb3f14855c4b0b diff --git a/HWFrom1-28-16(Merge Sort).playground/Contents.swift b/HWFrom1-28-16(Merge Sort).playground/Contents.swift index afdc1b6..70e5834 100644 --- a/HWFrom1-28-16(Merge Sort).playground/Contents.swift +++ b/HWFrom1-28-16(Merge Sort).playground/Contents.swift @@ -4,3 +4,107 @@ //Insert code here: +/* +Use recursion to implement at least one of the following sorting algorithms in Swift: + +// Insertion sort +func insertionSort(inout values: [Int]) { +} + +// Selection sort +func selectionSort(inout values: [Int]) { +} + +Requirements: +You may not use loops +Your implementations should be in-place (try not to create additional arrays) +You should implement and use additional helper functions + +Tips: +Add additional parameters to your helper functions to pass information between recursive calls +You can use the swap function to exchange two values in a mutable (var) array: +var array = [1, 2] +swap(&array[0], &array[1]) +array // [2, 1] + +Challenge: +Modify your implementation to work for any array of Comparable elements + +*/ + +// Insertion sort +//func insertionSort(var numberList: [Int]) { +// var x, y, key: Int +// for (x = 0; x < numberList.count; x++) { +// key = numberList[x] +// for (y = x; y > -1; y--) { +// if (key < numberList[y]) { +// numberList.removeAtIndex(y + 1) +// numberList.insert(key, atIndex: y) +// } +// } +// } +//} + +/* +func insertionSort(inout values: [Int], first: Int, last: Int) { + if (first < last) { + // sort all but not the last element + insertionSort(&values, first: first, last: last - 1) + // insert the last element in sorted order from the first through the last position + insertInOrder(values[last], values: values, first: first, last: last - 1) + } +} + +func insertionSort(inout values: [Int]) { + insertionSort(&values, first: 0, last: values.count - 1) +} + +func insertInOrder(key: Int, var values: [Int], first: Int, last: Int) { + if key >= values[last] { + values[last + 1] = key + } else if (first < last) { //if key < value[last] + values[last + 1] = values[last] + insertInOrder(key, values: values, first: first, last: last - 1) + } else { // first == last and element < values[last] + values[last + 1] = values[last] + values[last] = key + } +} + + +var arr = [2, 7, 9] +insertionSort(&arr) +*/ +/* +func select(xs: [Int], startingAt k: Int) -> Int { + var minIndex = k + for i in (k+1).. [Int] { + for sortedSoFar in 0.. Int { + let pivot = arr[first] + var lM = first + 1 + var rM = last + + while lM <= rM { + while lM <= rM && arr[lM] < pivot { + lM += 1 + } + while lM <= rM && arr[rM] > pivot { + rM -= 1 + } + if lM < rM { + swap(&arr[lM], &arr[rM]) + } + } + if first != rM { + swap(&arr[first], &arr[rM]) + } + return rM +} + +func quickSort(inout arr: [Int], first: Int, last: Int) { + if first >= last { return } + let splitPoint = partition(&arr, first: first, last: last) + quickSort(&arr, first: first, last: splitPoint - 1) + quickSort(&arr, first: splitPoint + 1, last: last) +} + +func quickSort(inout arr: [Int]){ + quickSort(&arr, first: 0, last: arr.count - 1) +} + +var numberList = [22, 3, 43, 55, 23, 29, 17, 90] +quickSort(&numberList) +*/ + + +//4)Write a function to generate an array of random numbers bounded between 1..<10,000 of size 10,000. + +//Int(arc4random_uniform(UInt32(10000))) + +//Compare the time it takes to run mergesort, quicksort, and quicksort with the median. +//https://gist.github.com/gummibeatz/8ff29bcec54d7e3ef683 +/* + +func profile(block:(()->())) { + let start = NSDate() + block() + let end = NSDate() + print(end.timeIntervalSinceDate(start)) +} + + +func partition(inout arr: [Int], first: Int, last: Int) -> Int { + let pivot = arr[first] + var lM = first + 1 + var rM = last + + while lM <= rM { + while lM <= rM && arr[lM] < pivot { + lM += 1 + } + while lM <= rM && arr[rM] > pivot { + rM -= 1 + } + if lM < rM { + swap(&arr[lM], &arr[rM]) + } + } + if first != rM { + swap(&arr[first], &arr[rM]) + } + return rM +} + +func quickSort(inout arr: [Int], first: Int, last: Int) { + if first >= last { return } + let splitPoint = partition(&arr, first: first, last: last) + quickSort(&arr, first: first, last: splitPoint - 1) + quickSort(&arr, first: splitPoint + 1, last: last) +} + +func quickSort(inout arr: [Int]){ + quickSort(&arr, first: 0, last: arr.count - 1) +} + +var arr = [Int(arc4random_uniform(UInt32(10000)))] + +//run your function/code inside the block below +profile({ + quickSort(&arr) +}) +*/ + + +//5)Describe the algorithmic difference between mergesort and quicksort. Where does the sorting happen? As the recursive calls are being pushed onto the stack or as they are being popped off? +/* +Quick sort does not require any additional memory while executing. It just sorts everything in the very array where the unsorted elements are present. On the other hand Merge sort requires extra memory (a lot of memory if the array is large). And the amount of extra memory required is O(n) which means it is directly proportional to the input size n. so the concluding statement is: "Quick sort is an IN-PLACE Algorithm while Merge sort is not." +"Quick Sort is NOT a stable sorting algorithm while Merge is." Quick sort is not stable because it exchanges the non adjacent elements. So preservance of order is not taken care of. The result might be stable or unstable. While Merge is a stable sort. +Quick sort is likely to run 1.2 to 1.4 times faster than Merge sort. It is always a good choice to use Quick over merge if Stability is not required. Moreover a good implementation of Quick sort is easier to code than a good implantation of Merge sort. Although Quick Sort's worse case of running time is O(n2) but it is always avoided using a randomized version of quick sort. +MergeSort exhibits end order or bottom up recursion in that all the significant actions take place after the recursive calls. This means that the array is split all the way down to singletons (of size 1) and that all actions take place on the way out of recursion. +In contrast, quickSort is exactly the opposite, namely top down recursion in the sense that the main action of partitioning is done before the recursive calls. + +*/ + +//6)Given an array of strings containing “[“,”]”,”{“,”}”,”(“,”)”. Output whether or not the parentheses are balanced. +//Good examples: () [] () ([]()[]) +//Bad examples: ( ( ] ([)] +// +func isBalanced(paren: [String]) -> Bool { + var stack = [String]() + for (var i = 0; i < paren.count; i++) { + let check = paren[i] + if (check == "(" || check == "[" || check == "{") { + stack.append(check); + } else if (stack.count == 0) { + return false + } else if (check == ")" && stack.removeLast() != "(") { + return false + } else if (check == "]" && stack.removeLast() != "[") { + return false + } else if (check == "}" && stack.removeLast() != "{") { + return false + } + } + return true; +} + +var good = ["(", ")", "[", "]", "(", ")", "(", "[", "]", "(", ")", "[", "]", ")"] +var bad = ["(", "(", "]", "(", "[", ")", "]"] +var test = [")", ")"] +var test2 = ["{","[", "]","}", "{", "}"] + +isBalanced(good) +isBalanced(bad) +isBalanced(test) +isBalanced(test2) +isBalanced([]) diff --git a/HWFrom1-31-16(Sets and HashMaps).playground/Contents.swift b/HWFrom1-31-16(Sets and HashMaps).playground/Contents.swift index c5841b0..3d55b58 100644 --- a/HWFrom1-31-16(Sets and HashMaps).playground/Contents.swift +++ b/HWFrom1-31-16(Sets and HashMaps).playground/Contents.swift @@ -1,20 +1,143 @@ //: https://docs.google.com/document/d/1T7tYRqpDPWoxarfmXqfRCHB-YqvA8-Qx_mEyy5smtfc -//1) -//a) +/* +//1) Write good hash functions for the following data types. Justify your choices and how they avoid collisions. -//b) +a) Int -//c) +b) struct Point: Hashable { + let x, y: Int +} +c) Array -//2) + +2) You moderate a popular mobile device discussion forum. You want to cut down on the vitriol and make your work easier, so you decide to implement a blacklist based system to automatically reject or approve posts. For example: + +moderate("I would never use a crApple product!") // false (reject) +moderate("I wish all these FANDROIDS would just shut up!") // false +moderate("M$ is the worst, Linux rules!") // false +moderate("Can’t we all just get along?") // true (approve) + +Write moderate(message: String) -> Bool, using a built-in Swift Set to manage your blacklist. Make your method case insensitive; it should block the word no matter what combination of upper and lowercase letters is used. + + +let blacklist: Set = ["crapple", "fandroid", "m$"] + +func moderate(message: String) -> Bool { + let words = message.componentsSeparatedByString(" ") + for word in words { + if blacklist.contains(word.lowercaseString) { + return false + } + } + return true +} + +moderate("I would never use a crApple product!") +moderate("something else") + +*/ +/* + +3) Your company makes a phonebook app, and your users have been complaining about how long it takes to look people’s numbers up. You decide to upgrade your archaic array-based system to a sleek, modern hash map. + +Write a phonebook class that uses either our HashMap from class or the built in Swift dictionary (your choice). It should implement the protocol below. It needs to support importing from the old array based format which used an array of tuples, like [(“Caleb”, “501-555-1234”), (“Mike”, “212-555-4321”), (“Jenny”, “345-867-5309”)] + + +protocol PhoneBookProtocol { + mutating func addPerson(name: String, phoneNumber: String) + mutating func removePerson(name: String) + mutating func importFrom(oldPhonebook: [(String, String)]) + func findPerson(name: String) -> String // Return phone # +} + +struct PhoneBook:PhoneBookProtocol, CustomStringConvertible { + + var phonebookDict = [String:String]() + + mutating func addPerson(name: String, phoneNumber: String) { + + + + } + + mutating func removePerson(name: String) { + + + } + + mutating func importFrom(oldPhonebook: [(String, String)]) { + + for i in 0.. String { + + + return name + } + + //Custom String Convertible + var description: String { + + return "{\(phonebookDict)}" + } +} +let oldPhoneBook = [("Caleb", "501-555-1234"), ("Mike", "212-555-4321"), ("Jenny", "345-867-5309")] +var newPhonebook = PhoneBook() +newPhonebook.importFrom(oldPhoneBook) +newPhonebook.description +*/ + +protocol PhoneBookProtocol { + mutating func addPerson(name: String, phoneNumber: String) + mutating func removePerson(name: String) + mutating func importFrom(oldPhonebook: [(String, String)]) + func findPerson(name: String) -> String? // Return phone # +} + +class PhoneBook: PhoneBookProtocol { + var storage: [String : String] = [:] // @{} + //var storage = Dictionary() + + func addPerson(name: String, phoneNumber: String) { + storage[name] = phoneNumber + } + + func removePerson(name: String) { + storage.removeValueForKey(name) + } + + func findPerson(name: String) -> String? { + return storage[name] + } + + func importFrom(oldPhonebook: [(String, String)]) { + for entry in oldPhonebook { + addPerson(entry.0, phoneNumber: entry.1) + } + } +} + +let oldData = [("Caleb", "501-555-1234"), ("Mike", "212-555-4321"), ("Jenny", "345-867-5309")] + +let phoneBook = PhoneBook() +phoneBook.importFrom(oldData) +phoneBook.findPerson("Jenny") -//3) \ No newline at end of file diff --git a/HWFrom2-05-16(Trees).playground/Contents.swift b/HWFrom2-05-16(Trees).playground/Contents.swift new file mode 100644 index 0000000..a0c3e71 --- /dev/null +++ b/HWFrom2-05-16(Trees).playground/Contents.swift @@ -0,0 +1,126 @@ +//https://docs.google.com/document/d/1te7mLS06MEYwETFSbVBqMrIzJ43GTEo5uuCiWdB0fyE/edit?usp=drivesdk + + +//1 + + +//Bonus1 + + +//Bonus2 + +/* + +Using the Swift binary tree implementation below (the Node class), implement a function that takes in a string containing a simple postfix mathematical expression, and returns a binary tree representing that expression using the process described here. + +Required: Build and return the binary tree representation of the expression. The following characters should be treated as operators: +- + +Bonus 1: Print the inorder traversal of the binary tree. +Bonus 2: Evaluate the expression (substituting integers for the letters in the expression). + +Tips: +You may use additional data structures—as suggested in the link above, you will at least want to use a stack. This can be done using the Array type in Swift. +Test your tree by checking to see if the string returned by postorderDescription is equal to the input string. + +Sample input: +"ab+cde+**" + +Template for the function you should implement: +func parseExpression(input: String) -> Node? { + // Your implementation here! + let operators: Set = ["+", "-", "*", "/"] + var stack: [Node] = [] + for character in input.characters { + // Do something for each character + } + return nil +} + +Binary tree implementation: +class Node { + let value: T + var left: Node? + var right: Node? + init(value: T) { + self.value = value + } +} + +extension Node: CustomStringConvertible { + var description: String { + return "\(value)" + } + var postorderDescription: String { + let lt = left?.postorderDescription ?? "" + let rt = right?.postorderDescription ?? "" + return lt + rt + description + } +} + + +*/ + +//: Playground - noun: a place where people can play + +import UIKit +import Foundation + +indirect enum Tree { + case Node(Int, left: Tree, right: Tree) + case Empty +} + +func printTree(tree: Tree, label: String = "t") -> String { + switch(tree) { + case let .Node(x, left, right): + var ret = "" + switch (left) { + case .Node: ret += "\(label) -> \(label)l\n" + case .Empty: ret += "\(label) -> \(label)L\n\(label)L[shape=point]\n" + } + switch (right) { + case .Node: ret += "\(label) -> \(label)r\n" + case .Empty: ret += "\(label) -> \(label)R\n\(label)R[shape=point]\n" + } + ret += "\(label)[label=\"\(x)\"]\n" + return ret + printTree(left, label: label + "l") + + printTree(right, label: label + "r") + case .Empty: + return "" + } +} + +func generateTree(depth: UInt32 = 10) -> Tree { + if (arc4random_uniform(depth) == 0) { + return Tree.Empty + } else { + return Tree.Node(Int(arc4random_uniform(100)), + left: generateTree(depth - 1), + right: generateTree(depth - 1)) + } +} + +// To show the tree, uncomment this and copy and paste the output into +// http://www.webgraphviz.com/ (or your local GraphViz installation) +//print("digraph g {\n" + printTree(tree) + "}") + +func dfs(tree: Tree, needle: Int) -> Bool { + switch (tree) { + case let .Node(value, left: left, right: right): + if value == needle { + return true + } else { + return dfs(left, needle: needle) || dfs(right, needle: needle) + } + case .Empty: + return false + } +} + +//let tree = Tree.Node(28, left: Tree.Empty, right: Tree.Empty) + +let tree = generateTree(8) + +print("diagraph g {\n" + printTree(tree) + "}") + +dfs(tree, needle: 18) diff --git a/HWFrom2-05-16(Trees).playground/contents.xcplayground b/HWFrom2-05-16(Trees).playground/contents.xcplayground new file mode 100644 index 0000000..5da2641 --- /dev/null +++ b/HWFrom2-05-16(Trees).playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/HWFrom2-05-16(Trees).playground/playground.xcworkspace/contents.xcworkspacedata b/HWFrom2-05-16(Trees).playground/playground.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/HWFrom2-05-16(Trees).playground/playground.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/HWFrom2-05-16(Trees).playground/timeline.xctimeline b/HWFrom2-05-16(Trees).playground/timeline.xctimeline new file mode 100644 index 0000000..bf468af --- /dev/null +++ b/HWFrom2-05-16(Trees).playground/timeline.xctimeline @@ -0,0 +1,6 @@ + + + + + diff --git a/HWfrom1-09-16(SwiftIntro).playground/Contents.swift b/HWfrom1-09-16(SwiftIntro).playground/Contents.swift index 488e9ed..e607a45 100644 --- a/HWfrom1-09-16(SwiftIntro).playground/Contents.swift +++ b/HWfrom1-09-16(SwiftIntro).playground/Contents.swift @@ -10,14 +10,86 @@ Use the link here to get the questions. Then code your solutions below. If it https://docs.google.com/document/d/1DQ2aCJ_yUZtazzCfb0PaS81bg61V2ZOSxpABh981xSo/edit +*/ -1) -2) +//1)Given an integer N, there is a list of size N-1 that is missing one number from 1 - N(inclusive). Find that number. + +func findMissingNumber1(N:Int, list:[Int]) -> Int { + var totalSumOfNArray = 0 + var totalSumOfList = 0 + for i in 1...N { + totalSumOfNArray += i + } + for i in list { + totalSumOfList += i + } + return totalSumOfNArray - totalSumOfList +} + +let arr = [1, 4, 6, 3, 2] +let N = arr.count + 1 + +findMissingNumber1(N, list: arr) + +//2)Given a list of size N containing numbers 1 - N (inclusive). return true if there are duplicates, false if not + +func hasDuplicates(arr4: [Int]) -> Bool { + + for i in 0..(arr) +// let result = Array(mySet) +// if result.count != arr.count { +// return true +// } +// return false +//} + +let arr4 = [1, 2, 3, 5] +hasDuplicates(arr4) + + + +//3)Given two lists, find the smallest value that exists in both lists. + +func smallestCommonNum(list1: [Int], list2: [Int]) -> Int? { + let set1 = Set(list1) + let set2 = Set(list2) + return set1.intersect(set2).minElement() +} + +let list1 = [3, 6, 9] +let list2 = [9, 12, 28] + +smallestCommonNum(list1, list2: list2) + + + +//4)Check to see if an integer is a palindrome don’t use casting +func isPalindrome(var num: Int) -> Bool { + let originalNum = num + var finalNum = 0 + while(num > 0) { + finalNum *= 10 + finalNum += num % 10 + num /= 10 + } + return finalNum == originalNum +} + +let num = 12021 +isPalindrome(num) -3) -4) -*/ diff --git a/HWfrom1-10-016(BigO).playground/Contents.swift b/HWfrom1-10-016(BigO).playground/Contents.swift index 2040d38..268c163 100644 --- a/HWfrom1-10-016(BigO).playground/Contents.swift +++ b/HWfrom1-10-016(BigO).playground/Contents.swift @@ -10,21 +10,319 @@ Use the link here to get the questions. Then code your solutions below. If it https://docs.google.com/document/d/1aF1imJUVahCSJAuN1OEm5lQXwpSFaAmVmAETKMM6PLQ/edit#heading=h.za36ai6n5fth +*/ + +/*1)With my new top of the line XJ452 supercomputer, memory access takes 1 picosecond, math operations take 3 picoseconds, and storing data in memory takes 10 picoseconds. My friend wrote a filter that makes a pixel more awesome, and takes 200 picoseconds to run. +a) How long would my computer take to execute the following code if the input image is 1000px wide by 2000px tall? What if it’s n by m? + + +Pixel **awesomeFilter(Pixel image[][], int width, int height) { + for (int i = 0; i < width; i++) { //10; 5*width; 14*width //w * ( + for (int j = 0; j < height; j++) { //10; 5*height; 14*height //h * ( + [image[i][j] makeMoreAwesome]; // 200 + } + } + return image; +} + +10+5w+14w+10w+5wh+14wh+200wh = 219wh +29w + 10 219nm + 29n + 10 + +O(m * n) + +b) What is the time complexity of this method, expressed in big O notation? Assume the image is square, and both dimensions are ‘n’. + +O(n^2) + +c) My friend sends me an improved version of his algorithm, makeEvenMoreAwesome, that takes into account the pixels around the image. He says it’s O(n2) in the amount of pixels in the image. What is the new time complexity of the method? + +O(n^4) since makeEvenMoreAwesome is O(n^2) + +*/ + +/*2)If foo(xs) is a function with time complexity n (where n is the size of the input array), and bar(xs) is a function with time complexity n2, what is the time complexity of each of the following snippets of code or algorithms? + + +a) for (int i = 0; i < n; i++) { n + for (int j = 0; j < n; j++) { n^2 + foo(xs); n + } +} +O(n^3) + +for (int i = 0; i < n; i++) { n + for (int j = 0; j < n; j++) { n^2 + bar(xs); + } +} +O(n^4) + +for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + // do cool stuff + } +} +O(n^2) + +Final: O(n^4) + +b) int frobnicate(ys, m) { + if (m == 0) { + return 0; + } + return ys[m] + frobnicate(ys, m - 1); +} +frobnicate(xs, n); +O(n) + + +Tip: Write down a table with n from 0 to 5 and trace through to find out how many times frobnicate is called with each value of n. + + +c) An algorithm that takes as its input a list of friends of length n, filters out duplicates using a method similar to our hasDuplicates method, sorts the list using merge sort (see bigocheatsheet.com), then prints each item to the screen. -1) +BOOL betterHasDuplicates(int xs[], int n) { +for (int i = 0; i < n; i++) { +for (int j = i; j < n; j++) { +if (i != j && xs[i] == xs[j]) { +return YES; +} +} +} +return NO; +} +O(n^2) -2) +//merge sort: split each element into partitions of size 1 +recursively merge adjancent partitions +for i = leftPartStartIndex to rightPartLastIndex inclusive +if leftPartHeadValue <= rightPartHeadValue +copy leftPartHeadValue +else: copy rightPartHeadValue +copy elements back to original array -3) +O(n(logn)) -4) +print each item +O(n) -5) +Final: O(n(logn)) = O(n^2) + O(n(logn)) + O(n) -6) -7) +d) An algorithm that searches the now-sorted list of friends for a specific friend (not including the time it takes to sort). +O(logn) Binary search */ +/*3)Look at the complexities for some common data structures at bigocheatsheet.com. Pick a good data structure for each of the following scenarios (there are sometimes multiple answers): + + +a) You get a large dataset of points of interest from an API when your app first runs. You build it once at the beginning, and then have to search it many times while the user pans around a map. + +Tree----A quad tree is a data structure comprising nodes which store a bucket of points and a bounding box. Any point which is contained within the node’s bounding box is added to its bucket. Once the bucket gets filled up, the node splits itself into four nodes, each with a bounding box corresponding to a quadrant of its parents bounding box. All points which would have gone into the parent’s bucket now go into one of its children’s buckets. + +https://robots.thoughtbot.com/how-to-handle-large-amounts-of-data-on-maps + +b) You get a small dataset of points of interest from an API every time the user pans the map. You construct the data set many times and only render it once, then you discard it and do another API search. + +Set or Array + +Tip: Constructing a dataset of size n means you have to call the data structure’s insert method n times. So if the data structure has an insert method that takes O(n2), the time to build it all from scratch is O(n3). + + +c) You used a linked list for your music app’s playlist feature, but now when people search their playlist, there’s a noticeable lag before loading results. Your competitor’s app is buttery smooth when searching, even showing results as you type. What data structure would allow you to more quickly search without compromising too much on the speed of inserting and deleting tracks, even in the worst case? + +Tree + +*/ + +/*4)Write an algorithm using one of the methods from exercise 1 (your choice) to calculate the factorial of a number n. What is the time complexity of your method in terms of the input value? + +func factorial(N: Int) -> Int { +if N == 1 { +return 1 +} else { +return N * factorial(N - 1) +} +} + +O(n!) + +*/ + +/*5)Write an Objective C or Swift function to multiply two numbers without using the * operator. Use the grade school method of multiplying by doing repeated addition. For instance, 5 * 8 = 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 = 40. Find the big O of your function in terms of n and m (the two operands). + +http://www.geeksforgeeks.org/multiply-two-numbers-without-using-multiply-division-bitwise-operators-and-no-loops/ +/* function to multiply two numbers n and m*/ +int multiply(int n, int m) +{ +/* 0 multiplied with anything gives 0 */ +if(m == 0) +return 0; + +/* Add n one by one */ +if(m > 0 ) +return (n + multiply(n, m-1)); + +/* the case where m is negative */ +if(m < 0 ) +return -multiply(n, -m+1); +} + +int main() +{ +printf("\n %d", multiply(5, -11)); +getchar(); +return 0; +} + +Read more: http://www.noexit4u.com/2013/03/c-program-to-multiply-two-numbers.html + + { + int n,m,i,prod=0; + clrscr(); + printf("Enter 1st number: "); + scanf("%d",&num1); + printf("Enter 2nd number: "); + scanf("%d",&num2); + for(i=1;i<=m;i++) + { + prod+=n; + } + printf("\n\n\nProduct of %d and %d is %d",n,m,prod); + getch(); +} + +O(m) + +*/ + +/*6)Look up Russian Peasant Multiplication. It’s a faster way to multiply numbers, especially on a binary computer (like yours!). Implement a new multiplication function using this technique and find the big O of your method. If you have trouble with implementing this, write a flow chart and find the big O based on that. (But it’s more satisfying to implement it and run it) + +// an Example below: http://www.cut-the-knot.org/Curriculum/Algebra/PeasantMultiplication.shtml +This is true in general: if tasked with applying the algorithm to finding the product of two numbers a and b, make the smaller number first, the larger one second. + +Now, let's see why the algorithm works. Since halving and doubling play such an important role in the algorithm, it should not come as a great surprise that its real foundation lies in the binary system. To obtain the binary representation of a number, the number is to be repeatedly divided by two, the remainders recorded and then written in the reverse order. Check now the "Show binary" box: + + +We see two additional columns: the first indicates the step (and a power of 2), the second contains the binary digits of 85 written from the bottom upwards: + +85 = 10101012, +which essentially means that + + +85 = 10101012 += 1·26 + 0·25 + 1·24 + 0·23 + 1·22 + 0·21 + 1·20 += 64 + 16 + 4 + 1. +Note that a binary digit is the remainder of division by 2: it is 1 for odd numbers and 0 for even numbers. Which bring forth the connection between the binary digits of the first multiplicand, 85 in our case, and the parity of the number in the column beneath it. The numbers are odd exactly when the remainder that appears to their left is 1. This makes the algorithm tick: + + +85×18 = (64 + 16 + 4 + 1)×18 += 1152 + 288 + 72 + 18 += 1530. +For the product 18×85 we get: + + +18 = 100102 += 1·24 + 0·23 + 0·22 + 1·21 + 0·20 += 16 + 2. +and subsequently + + +18×85 = (16 + 2)×85 += 1360 + 170 += 1530. + +O(logn) (as double input only add 1 step) + +Tip: Run through the method by hand a few times to see how it works and verify to yourself that it does. It’s a non-intuitive algorithm. This will hopefully also make the time complexity more clear. + +*/ + +/*7)Using the technique from exercise 4, profile the built in sorting method in objective C (use an NSMutableArray and google how to sort an array of numbers in objective C). Graph the result. Use spreadsheet formulas to add graph lines for n, n2, and n*log(n). (You’ll have to modify the factors to make them fit in the graph window and to be close to the graph of method execution time). Show that the sort method best fits n * log(n). + + +Not sure how to do this one. I did check the graph in http://bigocheatsheet.com though, still no idea at all. :( + + +//----Bubble sort---- +do +swapped = false +for i = 1 to indexOfLastUnsortedElement +if leftElement > rightElement +swap(leftElement, rightElement) +swapped = true +while swapped + + +//----Select sort---- +repeat (numOfElements - 1) times +set the first unsorted element as the minimum +for each of the unsorted elements +if element < currentMinimum +set element as new minimum +swap minimum with first unsorted position + + +//----Insert sort---- +mark first element as sorted +for each unsorted element +'extract' the element +for i = lastSortedIndex to 0 +if currentSortedElement > extractedElement +move sorted element to the right by 1 +else: insert extracted element + + +//----Merge sort---- +split each element into partitions of size 1 +recursively merge adjancent partitions +for i = leftPartStartIndex to rightPartLastIndex inclusive +if leftPartHeadValue <= rightPartHeadValue +copy leftPartHeadValue +else: copy rightPartHeadValue +copy elements back to original array + + +//----Quick sort---- +for each (unsorted) partition +set first element as pivot +storeIndex = pivotIndex + 1 +for i = pivotIndex + 1 to rightmostIndex +if element[i] < element[pivot] +swap(i, storeIndex); storeIndex++ +swap(pivot, storeIndex - 1) + + +//----R-Quick sort---- +for each (unsorted) partition +randomly select pivot, swap with first element +storeIndex = pivotIndex + 1 +for i = pivotIndex + 1 to rightmostIndex +if element[i] < element[pivot] +swap(i, storeIndex); storeIndex++ +swap(pivot, storeIndex - 1) + + +//----Count sort---- +create key (counting) array +for each element in list +increase the respective counter by 1 +for each counter, starting from smallest key +while counter is non-zero +restore element to list +decrease counter by 1 + + +//----Radix sort---- +create 10 buckets (queues) for each digit (0 to 9) +for each digit placing +for each element in list +move element into respective bucket +for each bucket, starting from smallest digit +while bucket is non-empty +restore element to list + +*/ + + diff --git a/HWfrom1-14-16(Logic+Discrete_Math).playground/Contents.swift b/HWfrom1-14-16(Logic+Discrete_Math).playground/Contents.swift index bc0df91..695786c 100644 --- a/HWfrom1-14-16(Logic+Discrete_Math).playground/Contents.swift +++ b/HWfrom1-14-16(Logic+Discrete_Math).playground/Contents.swift @@ -9,14 +9,146 @@ var str = "Hello, playground" Question 1: https://www.hackerrank.com/challenges/minimum-draws +<<<<<<< HEAD +Copy and paste your code: + +let firstLine = Int(readLine(stripNewline: true)!)! +for _ in 1...firstLine{ +let totalPairOfSocks = Int(readLine(stripNewline: true)!)! +print(totalPairOfSocks+1) +} + +//In its worst case scenario, n+1 socks (x) should Jim remove from his drawer until he finds a matching pair if there are n pairs socks in total. + +What is the big O runtime of your code?: O(n) +======= Copy and paste your code: What is the big O runtime of your code?: +>>>>>>> cde78394103ad73b556b455ae51bbdb81151cc7c Question 2: https://www.hackerrank.com/challenges/handshake Copy and paste your code: +<<<<<<< HEAD +let firstLine = Int(readLine(stripNewline: true)!)! +for _ in 1...firstLine{ +let numberOfPeople = Int(readLine(stripNewline: true)!)! +print(numberOfPeople*(numberOfPeople - 1)/2) +} + +// n*(n-1)/2 which is simplified from C(n, 2) + +What is the big O runtime of your code?: O(n^2) + +Question 3: https://www.hackerrank.com/challenges/connecting-towns + +Copy and paste your code: + +// ask user how many cases they want to test +let testCases = Int(readLine(stripNewline: true)!)! + + +// ask user for how many towns or nodes are in each case (in order) +for var x in 0..>>>>>> cde78394103ad73b556b455ae51bbdb81151cc7c */ diff --git a/HWfrom1-23-16(Recursion).playground/Contents.swift b/HWfrom1-23-16(Recursion).playground/Contents.swift index f7c3b5c..adce16d 100644 --- a/HWfrom1-23-16(Recursion).playground/Contents.swift +++ b/HWfrom1-23-16(Recursion).playground/Contents.swift @@ -7,6 +7,30 @@ var str = "Hello, playground" //https://docs.google.com/document/d/1KfnTOtPnBrYPFhBRAQPZBXor_mKDQvuJp4zwZbtHkRs/edit#heading=h.16sfqfmanxte +/* +Write a recursive method to print the binary representation of a decimal number to STDOUT. https://www.khanacademy.org/math/pre-algebra/applying-math-reasoning-topic/alternate-number-bases/v/decimal-to-binary - explanation of how to convert decimal to binary + + +func printBinaryRepresentation(number:Int) { + +} + +Sample Input: 5 +Sample Output: 101 + +2. Swap all adjacent elements in an array. All arrays will have an even size. Do not use loops. + +Sample input: [1,2,4,7,3,8,5,6] +Sample output: [2,1,7,4,8,3,6,5] + +3. Implement a binary search for a sorted array. Given an Int and an [Int]. Return true if the element exists in the array and false if not. + +Sample input: [1,2,7,23,23,167,9465] 167 +Sample output: true + + +*/ + //1 diff --git a/README.md b/README.md index 72f8968..e793e5d 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# unit-4-assignments -Assignments for unit 4 +# units-4-5-assignments +Assignments for units 4 and 5