Forked from Lascorbe/swift_2_guided_tour_solutions.swift
Created
June 11, 2016 23:44
Swift 2 Guided Tour - Solutions
This file contains 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
/****************/ | |
/* A Swift Tour */ | |
/****************/ | |
// | |
// This file contains all the solutions (I made) to the "A Swift Tour" exercises | |
// found in "The Swift Programming Language", you can find that guide here: | |
// https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/GuidedTour.html#//apple_ref/doc/uid/TP40014097-CH2-ID1 | |
// | |
// All examples are written using Swift 2.0 and Xcode 7 | |
// | |
// Disclaimer: `Work in Progress` | |
// | |
/* Simple Values */ | |
// Experiment: Create a constant with an explicit type of Float and a value of 4. | |
let implicitInteger = 70 | |
let implicitDouble = 70.0 | |
let explicitDouble: Double = 70 | |
let explicitDouble2: Double = 4 | |
// Experiment: 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 | |
// Experiment: Use \() to include a floating-point calculation in a string and to include someone’s name in a greeting. | |
let apples = 3.0 | |
let oranges = 5.0 | |
let fruitSummary = "I have \(apples + oranges + 0.5) pieces of fruit." | |
let name = "Luis" | |
let greetings = "🖖 \(name)." | |
/* Control Flow */ | |
// Experiment: Change optionalName to nil. What greeting do you get? Add an else clause that sets a different greeting if optionalName is nil. | |
var optionalName: String? = nil | |
var greeting = "Hello!" | |
if let name = optionalName { | |
greeting = "Hello, \(name)" | |
} | |
else { | |
greeting = "Hello, Irina Doe" | |
} | |
// Experiment: 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." | |
// default: | |
// let vegetableComment = "Everything tastes good in soup." | |
} | |
// Experiment: 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 = "Unknown" | |
for (kind, numbers) in interestingNumbers { | |
for number in numbers { | |
if number > largest { | |
largest = number | |
largestKind = kind | |
} | |
} | |
} | |
print(largest) | |
print(largestKind) | |
/* Functions and Closures */ | |
// Experiment: Remove the day parameter. Add a parameter to include today’s lunch special in the greeting. | |
func greet(name: String, lunchSpecial: String) -> String { | |
return "Hello \(name), today our spacial lunch is \(lunchSpecial)." | |
} | |
greet("Bob", lunchSpecial: "Secreto Iberico con reduccion de mosto") | |
// Experiment: Write a function that calculates the average of its arguments. | |
func average(numbers: Int...) -> Int { | |
var sum = 0 | |
for number in numbers { | |
sum += number | |
} | |
return sum/numbers.count | |
} | |
average(42, 597, 12, 435, 999, 12) | |
// Experiment: 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 | |
}) | |
/* Objects and Classes */ | |
// Experiment: Add a constant property with let, and add another method that takes an argument. | |
class Shape { | |
var numberOfSides = 0 | |
let constant = 0 | |
func simpleDescription() -> String { | |
return "A shape with \(numberOfSides) sides." | |
} | |
func methodWithArgument(numberOfSides: Int) { | |
self.numberOfSides = numberOfSides | |
} | |
} | |
// Experiment: Make another subclass of NamedShape called Circle that takes a radius and a name as arguments to its initializer. Implement an area() and a simpleDescription() 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." | |
} | |
} | |
import Darwin | |
let π = M_PI | |
class Circle: NamedShape { | |
var radius: Double | |
init(radius: Double, name: String) { | |
self.radius = radius | |
super.init(name: name) | |
} | |
func area() -> Double { | |
return π * pow(radius, 2) | |
} | |
override func simpleDescription() -> String { | |
return "A circle a radius of \(radius)." | |
} | |
} | |
let testCircle = Circle(radius: 5.5, name: "My Circle") | |
testCircle.area() | |
testCircle.simpleDescription() | |
/* Enumerations and Structures */ | |
// Experiment: 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.rawValue) | |
} | |
} | |
func isEqual(secondRank: Rank) -> Bool { | |
return self.rawValue == secondRank.rawValue | |
} | |
} | |
let ace = Rank.Ace | |
let aceRawValue = ace.rawValue | |
let jak = Rank.Jack | |
jak.isEqual(ace) | |
// Experiment: 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, | |
.Clubs: | |
return "black" | |
case .Hearts, | |
.Diamonds: | |
return "red" | |
} | |
} | |
} | |
let hearts = Suit.Hearts | |
let heartsDescription = hearts.simpleDescription() | |
let color = hearts.color() | |
// Experiment: Add a method to Card that creates a full deck of cards, with one card of each combination of rank and suit. | |
// after configuring `Suit` to get `rawValues` (`enum Suit: Int`) ... | |
struct Card { | |
var rank: Rank | |
var suit: Suit | |
func simpleDescription() -> String { | |
return "The \(rank.simpleDescription()) of \(suit.simpleDescription())" | |
} | |
static func fullDeck() -> [Card] { | |
var deck = [Card]() | |
var n = 1 | |
while let r = Rank(rawValue: n) { | |
var m = 0 | |
while let s = Suit(rawValue: m) { | |
deck.append(Card(rank: r, suit: s)) | |
m++ | |
} | |
n++ | |
} | |
return deck | |
} | |
} | |
let threeOfSpades = Card(rank: .Three, suit: .Spades) | |
let threeOfSpadesDescription = threeOfSpades.simpleDescription() | |
Card.fullDeck() | |
// Experiment: Add a third case to ServerResponse and to the switch. | |
enum ServerResponse { | |
case Result(String, String) | |
case CachedResult(String, String) | |
case Error(String) | |
} | |
let success = ServerResponse.Result("6:00 am", "8:09 pm") | |
let cached = ServerResponse.CachedResult("Check it on your Watch", "Do it again") | |
let failure = ServerResponse.Error("Out of cheese.") | |
switch cached { | |
case let .Result(sunrise, sunset): | |
let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)." | |
case let .CachedResult(noIdea, whatImDoing): | |
let serverResponse = "Sunrise is at \(noIdea) and sunset is at \(whatImDoing)." | |
case let .Error(error): | |
let serverResponse = "Failure... \(error)" | |
} | |
/* Protocols and Extensions */ | |
// Experiment: Write an enumeration that conforms to this protocol. | |
enum SimpleEnum: ExampleProtocol { | |
case OptionOne, OptionTwo, OptionThree | |
case OptionOneAdjusted, OptionTwoAdjusted, OptionThreeAdjusted | |
var simpleDescription: String { | |
get { | |
var desc = "A simplre enum of type " | |
switch self { | |
case .OptionOne: | |
desc += ".OptionOne" | |
case .OptionTwo: | |
desc += ".OptionTwo" | |
case .OptionThree: | |
desc += ".OptionThree" | |
case .OptionOneAdjusted: | |
desc += ".OptionOne (adjusted)" | |
case .OptionTwoAdjusted: | |
desc += ".OptionTwo (adjusted)" | |
case .OptionThreeAdjusted: | |
desc += ".OptionThree (adjusted)" | |
} | |
return desc | |
} | |
} | |
mutating func adjust() { | |
switch self { | |
case .OptionOne: | |
self = OptionOneAdjusted | |
case .OptionTwo: | |
self = OptionTwoAdjusted | |
case .OptionThree: | |
self = OptionThreeAdjusted | |
default: | |
print("Already adjusted") | |
} | |
} | |
} | |
var c = SimpleEnum.OptionThree | |
c.adjust() | |
c.simpleDescription | |
// Experiment: Write an extension for the Double type that adds an absoluteValue property. | |
import Darwin | |
extension Double { | |
var absoluteValue: Double { | |
get { | |
return fabs(self) | |
} | |
} | |
} | |
let double = -7.0 | |
print(double.absoluteValue) // <- This works | |
print(-7.0.absoluteValue) // <- This doesn't :S | |
/* Generics */ | |
// Experiment: Modify the anyCommonElements(_:_:) function to make a function that returns an array of the elements that any two sequences have in common. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment