Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jabukhari/1b88b6f0d43b43e6bfa5c837bad9d124 to your computer and use it in GitHub Desktop.
Save jabukhari/1b88b6f0d43b43e6bfa5c837bad9d124 to your computer and use it in GitHub Desktop.
Swift 2 Guided Tour - Solutions
/****************/
/* 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