Skip to content

[WIP] Generics Challenge #59

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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()

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='ios' executeOnSourceChanges='false'>
<timeline fileName='timeline.xctimeline'/>
</playground>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<Timeline
version = "3.0">
<TimelineItems>
<LoggerValueHistoryTimelineItem
documentLocation = "file:///Users/paulyi/Desktop/Development/Lambda%20iOS/ios-projects/Sprint%207/Concurrency%20II%20(7.3)/HungryDevelopers.playground#CharacterRangeLen=2081&amp;CharacterRangeLoc=33&amp;EndingColumnNumber=0&amp;EndingLineNumber=88&amp;StartingColumnNumber=0&amp;StartingLineNumber=4&amp;Timestamp=573004958.715552"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
</TimelineItems>
</Timeline>
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import UIKit

/// An unordered collection of unique elements that
/// may appear more than once in the collection.
public struct CountedSet<Element: Hashable> {
/// 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<Arrow>()
aCountedSet[.iron] // 0
var myCountedSet: CountedSet<Arrow> = [.iron, .magic, .iron, .silver, .iron, .iron]
myCountedSet[.iron] // 4
myCountedSet.remove(.iron) // 3
myCountedSet.remove(.dwarvish) // 0
myCountedSet.remove(.magic) // 0




Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='ios' executeOnSourceChanges='false'>
<timeline fileName='timeline.xctimeline'/>
</playground>