diff --git a/Sprint 7/Concurrency II (7.3)/HungryDevelopers.playground/Contents.swift b/Sprint 7/Concurrency II (7.3)/HungryDevelopers.playground/Contents.swift new file mode 100644 index 00000000..eaac43ef --- /dev/null +++ b/Sprint 7/Concurrency II (7.3)/HungryDevelopers.playground/Contents.swift @@ -0,0 +1,88 @@ +import UIKit + +import Foundation + +// 1 +class Spoon { + // 2 + func pickUp() { + while isPickedUp { continue } + lock.lock() + isPickedUp = true + lock.unlock() + } + + func putDown() { + lock.lock() + isPickedUp = false + lock.unlock() + } + + private let lock = NSLock() + private var isPickedUp: Bool = false +} +// 3 +class Developer { + + init(leftSpoon: Spoon, rightSpoon: Spoon, developer: String) { + self.leftSpoon = leftSpoon + self.rightSpoon = rightSpoon + self.developer = developer + } + // 5 + func think() { + print("\(developer) is thinking.") + usleep(useconds_t(Int.random(in: 1...1000))) + + leftSpoon.pickUp() + print("\(developer) picked up left spoon.") + + rightSpoon.pickUp() + print("\(developer) picked up right spoon.") + + return + } + // 6 + func eat() { + print("\(developer) is eating.") + usleep(useconds_t(Int.random(in: 1...1000))) + + leftSpoon.putDown() + print("\(developer) put down left spoon.") + + rightSpoon.putDown() + print("\(developer) put down right spoon.") + } + + func run() { + while true { + think() + eat() + } + } + + var leftSpoon: Spoon + var rightSpoon: Spoon + let developer: String +} + +// 7 +var spoon1 = Spoon() +var spoon2 = Spoon() +var spoon3 = Spoon() +var spoon4 = Spoon() +var spoon5 = Spoon() + +var developer1 = Developer(leftSpoon: spoon1, rightSpoon: spoon2, developer: "Paul") +var developer2 = Developer(leftSpoon: spoon2, rightSpoon: spoon3, developer: "Nate") +var developer3 = Developer(leftSpoon: spoon3, rightSpoon: spoon4, developer: "Jaspal") +var developer4 = Developer(leftSpoon: spoon4, rightSpoon: spoon5, developer: "Frulwinn") +var developer5 = Developer(leftSpoon: spoon5, rightSpoon: spoon1, developer: "Julian") + +let developers = [developer1, developer2, developer3, developer4, developer5] + +DispatchQueue.concurrentPerform(iterations: 5) { + // 8 + developers[$0].run() + +} diff --git a/Sprint 7/Concurrency II (7.3)/HungryDevelopers.playground/contents.xcplayground b/Sprint 7/Concurrency II (7.3)/HungryDevelopers.playground/contents.xcplayground new file mode 100644 index 00000000..9f5f2f40 --- /dev/null +++ b/Sprint 7/Concurrency II (7.3)/HungryDevelopers.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Sprint 7/Concurrency II (7.3)/HungryDevelopers.playground/timeline.xctimeline b/Sprint 7/Concurrency II (7.3)/HungryDevelopers.playground/timeline.xctimeline new file mode 100644 index 00000000..c0a6b326 --- /dev/null +++ b/Sprint 7/Concurrency II (7.3)/HungryDevelopers.playground/timeline.xctimeline @@ -0,0 +1,11 @@ + + + + + + + diff --git a/Sprint 7/Generics (7.2)/GenericsChallenge.playground/Contents.swift b/Sprint 7/Generics (7.2)/GenericsChallenge.playground/Contents.swift new file mode 100644 index 00000000..2ad94128 --- /dev/null +++ b/Sprint 7/Generics (7.2)/GenericsChallenge.playground/Contents.swift @@ -0,0 +1,80 @@ +import UIKit + +/// An unordered collection of unique elements that +/// may appear more than once in the collection. +public struct CountedSet { + /// Inserts the given element to the set, with + /// a count of 1 if the element is not yet present + /// or adding 1 to the count if it is. + @discardableResult + public mutating func insert(_ member: Element) -> Int { + _counts[member, default: 0] += 1 + return _counts[member]! + } + + /// Removes one instance of the given element from + /// the set. If the count goes to zero, the element is + /// removed from the set. If the element is not present, + /// the request is ignored. + @discardableResult + public mutating func remove(_ member: Element) -> Int { + + let memberCount = _counts[member, default: 0] + guard memberCount > 0 else { return 0 } + + guard memberCount > 1 else { _counts.removeValue(forKey: member); return 0 } + let newCount = _counts[member]! - 1 + _counts[member] = newCount + + return newCount + } + + /// Access an element count, returning 0 for any + /// element that does not appear in the counted set + public subscript(_ member: Element) -> Int { + return _counts[member, default: 0] + } + + /// Return the number of unique elements in the counted set + public var count: Int { return _counts.keys.count } + + /// A Boolean value that indicates whether the counted set is empty. + public var isEmpty: Bool { + return count == 0 + } + + internal var _counts: [Element: Int] +} + +extension CountedSet: ExpressibleByArrayLiteral { + // + // `ExpressibleByArrayLiteral` conformance + // + + /// Creates a counted set containing the elements of the given array literal. + /// + /// Do not call this initializer directly. It is used by the compiler when + /// you use an array literal. Instead, create a new counted set using an array + /// literal as its value by enclosing a comma-separated list of values in + /// square brackets. You can use an array literal anywhere a set is expected + /// by the type context. + public init(arrayLiteral elements: Element...) { + _counts = [:] + for element in elements { + _counts[element] = _counts[element, default: 0] + 1 + } + } +} + +enum Arrow { case iron, wooden, elven, dwarvish, magic, silver } +var aCountedSet = CountedSet() +aCountedSet[.iron] // 0 +var myCountedSet: CountedSet = [.iron, .magic, .iron, .silver, .iron, .iron] +myCountedSet[.iron] // 4 +myCountedSet.remove(.iron) // 3 +myCountedSet.remove(.dwarvish) // 0 +myCountedSet.remove(.magic) // 0 + + + + diff --git a/Sprint 7/Generics (7.2)/GenericsChallenge.playground/contents.xcplayground b/Sprint 7/Generics (7.2)/GenericsChallenge.playground/contents.xcplayground new file mode 100644 index 00000000..9f5f2f40 --- /dev/null +++ b/Sprint 7/Generics (7.2)/GenericsChallenge.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file