-
-
Save rainypixels/ae8c3b0021acc7673416 to your computer and use it in GitHub Desktop.
| /* | |
| Swift Programming Language Guide | |
| "A Swift Tour" Solutions | |
| https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/GuidedTour.html#//apple_ref/doc/uid/TP40014097-CH2-XID_1 | |
| These are the solutions to all the "experiments" in the pre-release Swift Programming Guide | |
| (released on the same day Apple announced Swift). A couple of things worth noting: | |
| 1. Swift syntax, e.g. array declarations, has changed since I releasd these. So this code will | |
| probably cause some errors when you paste it into a playground. Should be easy enough to fix | |
| (and maybe a good exercise unto itself? :) ) | |
| 2. As some of the commenters have pointed out, I messed up a few solutions. So, please be sure | |
| to check the comments for the correct answers. | |
| */ | |
| import Cocoa | |
| // Create a constant with an explicit type of Float and a value of 4. | |
| let valueOfFour: Float = 4.0 | |
| // Try removing the conversion to String from the last line. What error do you get? | |
| let label = "The width is " | |
| let width = 94 | |
| let widthLabel = label + String(width) | |
| // let widthLabel = label + width | |
| // Use \() to include a floating-point calculation in a string and to include someone’s name in a greeting. | |
| let height:Float = 68 | |
| let name = "Yoshi" | |
| let myHeight = "\(name)'s height is \(height + 0.5) inches" | |
| // Change optionalName to nil. What greeting do you get? Add an else clause that sets a different greeting if optionalName is nil. | |
| let individualScores = [75, 43, 103, 87, 12] | |
| var teamScore = 0 | |
| for score in individualScores { | |
| if score > 50 { | |
| teamScore += 3 | |
| } else { | |
| teamScore += 1 | |
| } | |
| } | |
| teamScore | |
| var optionalString: String? = "Hello" | |
| optionalString == nil | |
| var optionalName: String? = nil | |
| var greeting = "Hello!" | |
| if let name = optionalName { | |
| greeting = "Hello, \(name)" | |
| } else { | |
| greeting = "Hello, Yoshi" | |
| } | |
| greeting | |
| // Try removing the default case. What error do you get? | |
| let vegetable = "red pepper" | |
| switch vegetable { | |
| case "celery": | |
| let vegetableComment = "Add some raisins and make ants on a log." | |
| case "cucumber", "watercress": | |
| let vegetableComment = "That would make a good tea sandwich." | |
| case let x where x.hasSuffix("pepper"): | |
| let vegetableComment = "Is it a spicy \(x)?" | |
| default: | |
| let vegetableComment = "Everything tastes good in soup." | |
| } | |
| // Add another variable to keep track of which kind of number was the largest, as well as what that largest number was. | |
| let interestingNumbers = [ | |
| "Prime": [2, 3, 5, 7, 11, 13], | |
| "Fibonacci": [1, 1, 2, 3, 5, 8], | |
| "Square": [1, 4, 9, 16, 25], | |
| ] | |
| var largest = 0 | |
| var largestKind = "" | |
| for (kind, numbers) in interestingNumbers { | |
| for number in numbers { | |
| if number > largest { | |
| largest = number | |
| largestKind = kind | |
| } | |
| } | |
| } | |
| largest | |
| largestKind | |
| // Remove the day parameter. Add a parameter to include today’s lunch special in the greeting. | |
| func greet(name: String, special: String) -> String { | |
| return "Hello \(name)! Today's special is \(special)." | |
| } | |
| greet("Bob", "Meatloaf") | |
| // Write a function that calculates the average of its arguments. | |
| func average (numbers:Int...) -> Float { | |
| var sum = 0 | |
| var total = 0 | |
| for n in numbers { | |
| sum += n | |
| total++ | |
| } | |
| return Float(sum / total) | |
| } | |
| average(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) | |
| // Rewrite the closure to return zero for all odd numbers. | |
| var numbers = [20, 19, 7, 12] | |
| numbers.map({ | |
| (number: Int) -> Int in | |
| var result = 0 | |
| if number % 2 == 0 { | |
| result = 3 * number | |
| } | |
| return result | |
| }) | |
| // Add a constant property with let, and add another method that takes an argument. | |
| class Shape { | |
| var numberOfSides = 0 | |
| let numberOfDimensions = 3 | |
| func simpleDescription() -> String { | |
| return "A shape with \(numberOfSides) sides." | |
| } | |
| func isNDimensional(dimensions:Int) -> Bool { | |
| var response = false | |
| if (numberOfDimensions == dimensions) { | |
| response = true | |
| } | |
| return response | |
| } | |
| } | |
| var shape = Shape() | |
| shape.isNDimensional(3) | |
| // Make another subclass of NamedShape called Circle that takes a radius and a name as arguments to its initializer. Implement an area and a describe method on the Circle class. | |
| class NamedShape { | |
| var numberOfSides: Int = 0 | |
| var name: String | |
| init(name: String) { | |
| self.name = name | |
| } | |
| func simpleDescription() -> String { | |
| return "A shape with \(numberOfSides) sides." | |
| } | |
| } | |
| class Square: NamedShape { | |
| var sideLength: Double | |
| init(sideLength: Double, name: String) { | |
| self.sideLength = sideLength | |
| super.init(name: name) | |
| numberOfSides = 4 | |
| } | |
| func area() -> Double { | |
| return sideLength * sideLength | |
| } | |
| override func simpleDescription() -> String { | |
| return "A square with sides of length \(sideLength)." | |
| } | |
| } | |
| let test = Square(sideLength: 5.2, name: "my test square") | |
| test.area() | |
| test.simpleDescription() | |
| class Circle: NamedShape { | |
| var radius: Double = 0; | |
| init(radius: Double, name: String) { | |
| self.radius = radius; | |
| super.init(name:name) | |
| } | |
| func area() -> Double { | |
| return M_PI * radius * radius | |
| } | |
| override func simpleDescription() -> String { | |
| return "A circle with radius of \(radius)" | |
| } | |
| } | |
| let test1 = Circle(radius: 9.9, name: "my test circle") | |
| test1.area() | |
| test1.simpleDescription() | |
| // Write a function that compares two Rank values by comparing their raw values. | |
| enum Rank: Int { | |
| case Ace = 1 | |
| case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten | |
| case Jack, Queen, King | |
| func simpleDescription() -> String { | |
| switch self { | |
| case .Ace: | |
| return "ace" | |
| case .Jack: | |
| return "jack" | |
| case .Queen: | |
| return "queen" | |
| case .King: | |
| return "king" | |
| default: | |
| return String(self.toRaw()) | |
| } | |
| } | |
| } | |
| let ace = Rank.Ace | |
| let aceRawValue = ace.toRaw() | |
| func isSameRank (first: Rank, second: Rank) -> Bool { | |
| return first.toRaw() == second.toRaw() | |
| } | |
| isSameRank (Rank.Ace, Rank.Queen) | |
| isSameRank (Rank.Two, Rank.Two) | |
| // Add a color method to Suit that returns “black” for spades and clubs, and returns “red” for hearts and diamonds. | |
| enum Suit { | |
| case Spades, Hearts, Diamonds, Clubs | |
| func simpleDescription() -> String { | |
| switch self { | |
| case .Spades: | |
| return "spades" | |
| case .Hearts: | |
| return "hearts" | |
| case .Diamonds: | |
| return "diamonds" | |
| case .Clubs: | |
| return "clubs" | |
| } | |
| } | |
| func color () -> String { | |
| switch self { | |
| case .Spades: | |
| return "black" | |
| case .Clubs: | |
| return "black" | |
| case .Hearts: | |
| return "red" | |
| case .Diamonds: | |
| return "red" | |
| } | |
| } | |
| } | |
| let hearts = Suit.Hearts | |
| let heartsDescription = hearts.simpleDescription() | |
| hearts.color() | |
| Suit.Spades.color() | |
| // Add a method to Card that creates a full deck of cards, with one card of each combination of rank and suit. | |
| struct Card { | |
| var rank: Rank | |
| var suit: Suit | |
| func simpleDescription() -> String { | |
| return "The \(rank.simpleDescription()) of \(suit.simpleDescription())" | |
| } | |
| } | |
| let threeOfSpades = Card(rank: .Three, suit: .Spades) | |
| let threeOfSpadesDescription = threeOfSpades.simpleDescription() | |
| func createDeck() -> Card[] { | |
| var deck = Array (count: 52, repeatedValue: Card(rank: .Ace, suit: .Spades)) | |
| var suits = [Suit.Spades, Suit.Hearts, Suit.Diamonds, Suit.Clubs]; | |
| var counter = 0; | |
| for i in 1...13 { | |
| for suit in suits { | |
| deck[counter++] = Card (rank: Rank.fromRaw(i)!, suit: suit) | |
| } | |
| } | |
| return deck | |
| } | |
| func printDeck (deck: Card[]) { | |
| for card in deck { | |
| println (card.simpleDescription()) | |
| } | |
| } | |
| let deck = createDeck() | |
| printDeck(deck) | |
| // Add a third case to ServerResponse and to the switch. | |
| enum ServerResponse { | |
| case Result(String, String, String) | |
| case Error(String) | |
| } | |
| let success = ServerResponse.Result("6:00 am", "8:09 pm", "14:09h") | |
| let failure = ServerResponse.Error("Out of cheese.") | |
| switch success { | |
| case let .Result(sunrise, sunset, daylight): | |
| let serverResponse = "Sunrise is at \(sunrise), sunset is at \(sunset), and total daylight is \(daylight)." | |
| case let .Error(error): | |
| let serverResponse = "Failure... \(error)" | |
| } | |
| // Write an enumeration that conforms to this protocol. | |
| protocol ExampleProtocol { | |
| var simpleDescription: String { get } | |
| mutating func adjust() | |
| } | |
| class SimpleClass: ExampleProtocol { | |
| var simpleDescription: String = "A very simple class." | |
| var anotherProperty: Int = 69105 | |
| func adjust() { | |
| simpleDescription += " Now 100% adjusted." | |
| } | |
| } | |
| var a = SimpleClass() | |
| a.adjust() | |
| let aDescription = a.simpleDescription | |
| struct SimpleStructure: ExampleProtocol { | |
| var simpleDescription: String = "A simple structure" | |
| mutating func adjust() { | |
| simpleDescription += " (adjusted)" | |
| } | |
| } | |
| var b = SimpleStructure() | |
| b.adjust() | |
| let bDescription = b.simpleDescription | |
| enum SimpleEnum: ExampleProtocol { | |
| case A, B, AA, BB | |
| var simpleDescription: String { | |
| get { | |
| switch self { | |
| case .A: | |
| return "A simple enum: A" | |
| case .B: | |
| return "A simple enum: B" | |
| case .AA: | |
| return "A simple enum: AA" | |
| case .BB: | |
| return "A simple enum: BB" | |
| } | |
| } | |
| } | |
| mutating func adjust() { | |
| switch self { | |
| case .A: | |
| self = A | |
| case .B: | |
| self = B | |
| case .AA: | |
| self = A | |
| case .BB: | |
| self = B | |
| } | |
| } | |
| } | |
| var c = SimpleEnum.AA | |
| c.simpleDescription | |
| c.adjust() | |
| c.simpleDescription | |
| // Write an extension for the Double type that adds an absoluteValue property. | |
| extension Double { | |
| var abs: Double { | |
| get { | |
| return fabs(self) | |
| } | |
| } | |
| } | |
| var myDouble = -17.8 | |
| myDouble.abs | |
| // Modify the anyCommonElements function to make a function that returns an array of the elements that any two sequences have in common. | |
| func commonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> Array<T.GeneratorType.Element> { | |
| var result = Array<T.GeneratorType.Element>() | |
| for lhsItem in lhs { | |
| for rhsItem in rhs { | |
| if lhsItem == rhsItem { | |
| result.append(lhsItem) | |
| } | |
| } | |
| } | |
| return result | |
| } | |
| var result = commonElements([1, 2, 3], [3, 2]) | |
| println(result) |
// This is the solution I came up with for the Swift 3 version of the last exercise.
func anyCommonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> [T.Iterator.Element]
where T.Iterator.Element: Equatable, T.Iterator.Element == U.Iterator.Element {
var result = Array<T.Iterator.Element>()
for lhsItem in lhs {
for rhsItem in rhs {
if lhsItem == rhsItem {
result.append(lhsItem)
}
}
}
return result
}
// Thanks to jpromano (see solution from Feb 21) for the test case design.
let commonNumberList = anyCommonElements([7,9,22,4,17,100], [4,9,33,2,99])
print("common Numbers = \(commonNumberList)")
let commonStringList = anyCommonElements(["a","b","c"],["d","e","f","c","b"])
print("common Strings = \(commonStringList)")
// Modify the anyCommonElements function to make a function that returns an array of the elements that any two sequences have in common.
func commonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> Array<T.GeneratorType.Element> {
var result = Array<T.GeneratorType.Element>()
for lhsItem in lhs {
for rhsItem in rhs {
if lhsItem == rhsItem {
result.append(lhsItem)
}
}
}
return result
}
var result = commonElements([1, 2, 3], [3, 2])
println(result)
Anyone please expain the last experiment???? I cannot understand generics part.
For some reason I keep getting \n showing up in the output section after seemingly random outputs.
for example: On second page Line 14: print(teamScore) - Output: 11\n
My version of the last (swift 4.2 tour) experiment:
func findCommonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> [T.Iterator.Element]
where T.Iterator.Element: Equatable, T.Iterator.Element == U.Iterator.Element {
var result: [T.Iterator.Element] = []
for lhsItem in lhs {
for rhsItem in rhs {
if lhsItem == rhsItem && !result.contains(lhsItem) {
result.append(lhsItem)
}
}
}
return result
}
findCommonElements([1, 3, 5, 24, 7], [7, 8, 7, 1])Line 221 and 222 need to get changed to
isSameRank (Rank.Ace, Rank.Queen)
isSameRank (Rank.Two, Rank.Two)
because of compiler error:
error: Enumerations and Structures.xcplaygroundpage:26:11: error: missing argument labels 'first:second:' in call isSameRank(Rank.jack, Rank.queen)
Tried to create pull request but failed.
Personally I was hoping to use the already provided sumOf function to calculate the sum for the avgOf function. How might one achieve this?
something to the effect of:
avgOf(sumOf(numbers: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10))