-
-
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) |
sgtbilge
commented
Nov 11, 2016
•
// 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.