Last active
December 31, 2019 10:15
-
-
Save creativeportfolio-ios/0e72c6c8ff8c6b5b93556c88fd06e0fb to your computer and use it in GitHub Desktop.
Oursky Developer Pre-Test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import UIKit | |
| extension Array where Element: Hashable { | |
| /** | |
| In swift, An Set array to determine each item available, so the time complexity is O(n) And find an item in an second array so time complexity is O(m) and equal operation is all constant, so they are O(m^n) | |
| Time Complexity: O(m^n) | |
| */ | |
| func isSubset(to: [Element]) -> Bool{ | |
| return Set(self).isSubset(of: Set(to)) | |
| } | |
| } | |
| // How to use | |
| debugPrint([“A”,“B”,“C”,“D”,“E”].isSubset(to: [“A”,“E”,“D”])) // true | |
| debugPrint([“A”,“B”,“C”,“D”,“E”].isSubset(to: [“A”,“D”,“Z”])) // false | |
| debugPrint([“A”,“D”,“E”].isSubset(to: [“A”,“A”,“D”,“E”])) // true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| We can use Swift inbuilt Deque as a Node ended queue to store the cache keys, with the descending Weight of reference from front to back and a set container to check presence of a key. But remove a key from the Deque using remove(node:), it takes O(N) time. This can be optimized by storing a reference (iterator) to each key in a Equatable. | |
| */ | |
| import UIKit | |
| class Node: Equatable { | |
| var key: Int | |
| var value: Int | |
| var weight: Int | |
| var next: Node? | |
| weak var prev: Node? | |
| init(key: Int, value: Int, weight: Int) { | |
| self.key = key | |
| self.value = value | |
| self.weight = weight | |
| } | |
| static func == (lhs: Node, rhs: Node) -> Bool { | |
| return lhs.key == rhs.key | |
| } | |
| } | |
| class NodeCache { | |
| var capacity: Int | |
| var dict: [Int: Node] | |
| var head: Node? | |
| var tail: Node? | |
| var nodeArray:[Int] = [] | |
| /// Number of node on cache | |
| public var count: Int { | |
| guard var node = head else { | |
| return 0 | |
| } | |
| var count = 1 | |
| while let next = node.next { | |
| node = next | |
| count += 1 | |
| } | |
| return count | |
| } | |
| /// To fetch a particular index node to cache | |
| /// - Parameter index: index of node | |
| private func node(at index: Int) -> Node { | |
| if index == 0 { | |
| return head! | |
| } else { | |
| var node = head!.next | |
| for _ in 1..<index { | |
| node = node?.next | |
| if node == nil { | |
| break | |
| } | |
| } | |
| return node! | |
| } | |
| } | |
| /// init cache object with max capacity | |
| /// - Parameter capacity: capacity of node objects | |
| init(_ capacity: Int) { | |
| self.capacity = capacity | |
| self.dict = [Int: Node]() | |
| } | |
| /// Get value of node suing key | |
| /// - Parameter key: key for node value | |
| func get(_ key: Int) -> Int { | |
| if let node = dict[key] { | |
| remove(node: node) | |
| add(node: node) | |
| return node.value | |
| } else { | |
| return -1 | |
| } | |
| } | |
| /// Add value in cache using put function | |
| /// - Parameter key: key of node object | |
| /// - Parameter value: value for node | |
| /// - Parameter weight: node weight | |
| func put(_ key: Int, _ value: Int, _ weight: Int) { | |
| if let node = dict[key] { | |
| remove(node: node) | |
| } | |
| let newNode = Node(key: key, value: value, weight: weight) | |
| dict[key] = newNode | |
| add(node: newNode) | |
| if dict.count > capacity, let first = head { | |
| remove(node: first) | |
| dict.removeValue(forKey: first.key) | |
| } | |
| } | |
| /// Add node on cache | |
| /// - Parameter node: node value | |
| private func add(node: Node) { | |
| var index = 0 | |
| for i in nodeArray { | |
| if i > node.weight { | |
| break | |
| } else { | |
| index += 1 | |
| } | |
| } | |
| insert(node, at: index) | |
| nodeArray.insert(node.weight, at: index) | |
| } | |
| /// insert new node on particular index | |
| /// - Parameter node: new node object | |
| /// - Parameter index: index to add node on cache | |
| private func insert(_ node: Node, at index: Int) { | |
| let newNode = node | |
| if index == 0 { | |
| newNode.next = head | |
| head?.prev = newNode | |
| head = newNode | |
| } else { | |
| let prev = self.node(at: index-1) | |
| let next = prev.next | |
| newNode.prev = prev | |
| newNode.next = prev.next | |
| prev.next = newNode | |
| next?.prev = newNode | |
| } | |
| } | |
| /// Remove node from cache | |
| /// - Parameter node: node object to remove | |
| public func remove(node: Node) { | |
| if let index = nodeArray.firstIndex(of: node.weight) { | |
| nodeArray.remove(at: index) | |
| } | |
| let prev = node.prev | |
| let next = node.next | |
| if let prev = prev { | |
| prev.next = next | |
| } else { | |
| head = next | |
| } | |
| next?.prev = prev | |
| node.prev = nil | |
| node.next = nil | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // var and let are both used for variable declaration in javascript but the difference between them is that var is function scoped and let is block scoped. | |
| // We need a block scoped on this code so change var to let. | |
| //Solution of this function: | |
| function createArrayOfFunctions(y) { | |
| var arr = []; | |
| for(let i = 0; i < y; i++) { | |
| arr[i] = function(x) { return x + i; } | |
| } | |
| return arr; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import UIKit | |
| struct Fibonacci { | |
| fileprivate var objects: [Int] = [Int]() | |
| fileprivate var fiboSequence: UnfoldSequence<Int, (Int, Int)> | |
| init() { | |
| fiboSequence = sequence(state: (1, 0), next: { ($0.1, $0 = ($0.1, $0.0 + $0.1)).0 }) | |
| } | |
| mutating func next(ofValue value: Int) -> Int { | |
| // Array last object is greater than of value means `objects` contain a next fibonacci value | |
| if let lastObject = objects.last, lastObject > value { | |
| // Check the last object is not next fibonacci of value | |
| if let secondLast = objects.secondLast, secondLast < value { | |
| return lastObject | |
| } | |
| // Fetch a next fibonacci value for enter value | |
| return objects.first { return $0 > value } ?? 0 | |
| } else { | |
| // Value is not contain on `objects` array then fetch next fibonacci and add on `objects` | |
| if let nextFibo = fiboSequence.next() { | |
| objects.append(nextFibo) | |
| } | |
| } | |
| return next(ofValue: value) | |
| } | |
| static func nextFibonacciValues(_ values: [Int]) -> [Int] { | |
| var fibonacci = Fibonacci() | |
| return values.map { fibonacci.next(ofValue: $0) } | |
| } | |
| } | |
| extension Array { | |
| var secondLast: Element? { | |
| if let lastIndex = indices.last, | |
| indices.contains(lastIndex - 1) { | |
| return self[lastIndex - 1] | |
| } | |
| return nil | |
| } | |
| } | |
| // How to use: | |
| print(Fibonacci.nextFibonacciValues([1,22,9,0])) | |
| // Output: [2, 34, 13, 1] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment