Checkpoint


Aug. 20, 2022

Checkpoint 9

/* Your challenge is this: write a function that accepts an optional array of integers, and returns one randomly. If the array is missing or empty, return a random number in the range 1 through 100.

If that sounds easy, it’s because I haven’t explained the catch yet: I want you to write your function in a single line of code. No, that doesn’t mean you should just write lots of code then remove all the line breaks – you should be able to write this whole thing in one line of code.

Aug. 17, 2022

Checkpoint 8

/* Your challenge is this: make a protocol that describes a building, adding various properties and methods, then create two structs, House and Office, that conform to it.

Your protocol should require the following: A property storing how many rooms it has. A property storing the cost as an integer (e.g. 500,000 for a building costing $500,000.) A property storing the name of the estate agent responsible for selling the building. A method for printing the sales summary of the building, describing what it is along with its other properties.

Aug. 15, 2022

Checkpoint 7

/* Your challenge is this: make a class hierarchy for animals, starting with Animal at the top, then Dog and Cat as subclasses, then Corgi and Poodle as subclasses of Dog, and Persian and Lion as subclasses of Cat.

But there’s more: The Animal class should have a legs integer property that tracks how many legs the animal has. The Dog class should have a speak() method that prints a generic dog barking string, but each of the subclasses should print something slightly different. The Cat class should have a matching speak() method, again with each subclass printing something different. The Cat class should have an isTame Boolean property, provided using an initializer.

Jul. 23, 2022

Checkpoint 6

/*
create a struct to store information about a car, including its model, number of seats, and current gear, then add a method to change gears up or down. Have a think about variables and access control: what data should be a variable rather than a constant, and what data should be exposed publicly? Should the gear-changing method validate its input somehow?
*/

struct Car {
    static let maxGear = 10
    static let minGear = 1
    var model = "no model"
    var seats = 4
    private (set) var currentGear = Car.minGear
    
    init (model: String, seats: Int) {
        self.model = model
        self.seats = seats
    }
    
    mutating func gearUp() {
        if currentGear < Car.maxGear{
            currentGear += 1
        }
    }
    
    mutating func gearDown() {
        if currentGear > Car.minGear{
            currentGear -= 1
        }
    }
    
}

var myUte = Car(model: "Rodeo", seats:2)
print("My \(myUte.model) has \(myUte.seats) seats and is in gear: \(myUte.currentGear)")
myUte.gearDown()
print("My \(myUte.model) has \(myUte.seats) seats and is in gear: \(myUte.currentGear)")
myUte.gearUp()
print("My \(myUte.model) has \(myUte.seats) seats and is in gear: \(myUte.currentGear)")

Jul. 16, 2022

Checkpoint 5

/*
 Your input is this:
 
 let luckyNumbers = [7, 4, 38, 21, 16, 15, 12, 33, 31, 49]
 
 Your job is to:
 
 Filter out any numbers that are even
 Sort the array in ascending order
 Map them to strings in the format “7 is a lucky number”
 Print the resulting array, one item per line
 
 So, your output should be as follows:
 
 7 is a lucky number
 15 is a lucky number
 21 is a lucky number
 31 is a lucky number
 33 is a lucky number
 49 is a lucky number
 */

let luckyNumbers = [7, 4, 38, 21, 16, 15, 12, 33, 31, 49]

func isNumberOdd(number:Int) -> Bool {
    return number%2 == 1
}

let filteredNumbers = luckyNumbers.filter(isNumberOdd)

// this closure effectively does nothing
let sortedNumbers = filteredNumbers.sorted(by: {$0<$1}) 

let mappedNumbers = sortedNumbers.map({ String($0)+" is a lucky number" })

for i in 0..<mappedNumbers.count {
    print(mappedNumbers[i])
}

Jul. 13, 2022

Checkpoint 4

/*
 The challenge is this: write a function that accepts an integer from 1 through 10,000, and returns the integer square root of that number. That sounds easy, but there are some catches:
 
 You can’t use Swift’s built-in sqrt() function or similar – you need to find the square root yourself.
 If the number is less than 1 or greater than 10,000 you should throw an “out of bounds” error.
 You should only consider integer square roots – don’t worry about the square root of 3 being 1.732, for example.
 If you can’t find the square root, throw a “no root” error.
 */

enum IntSqrtError: Error {
    case low, high, noIntRoot
}

func calculateIntSqrt(_ number:Int) throws -> Int  {
    let lowerBound = 1
    let upperBound = 10_000
    if number < lowerBound {throw IntSqrtError.low}
    if number > upperBound {throw IntSqrtError.high}
    // brute force sqrt finder
    for i in lowerBound...number {
        if i*i == number {
            return i
        }
    }
    // none found or we would have returned by now
    throw IntSqrtError.noIntRoot
}

do {
    try print(calculateIntSqrt(5929))
} catch IntSqrtError.low {
    print("Lower bound error")
} catch IntSqrtError.high {
    print("Upper bound error")
} catch IntSqrtError.noIntRoot {
    print("No integer root")
} catch {
    assert(false)
    print("Unknown error")
}

Jul. 13, 2022

Checkpoint 4 optimisation

The Checkpoint 4 task was to find an integer square root of numbers up to 10000. My first pass solution was:

func calculateIntSqrt(_ number:Int) throws -> Int  {
    let lowerBound = 1
    let upperBound = 10_000
    if number < lowerBound {throw IntSqrtError.low}
    if number > upperBound {throw IntSqrtError.high}
    // brute force sqrt finder
    for i in lowerBound...number {
        if i*i == number {
            return i
        }
    }
    // none found or we would have returned by now
    throw IntSqrtError.noIntRoot
}

Although not coded for speed, there are a couple of subtle optimisations here; the first is that it gives up once it gets to the number instead of going up to the end (it assumes the square root of a number can’t be greater than the number), and the second is that it counts up from the bottom rather than down from the top - I’m assuming the bottom of the range is richer in square roots than the top.

Jul. 8, 2022

Checkpoint 3

 /*
 If it’s a multiple of 3, print “Fizz”
 If it’s a multiple of 5, print “Buzz”
 If it’s a multiple of 3 and 5, print “FizzBuzz”
 Otherwise, just print the number.
 */

for i in 1...100 {

    let isMultOfThree = (i % 3 == 0)
    let isMultOfFive = (i % 5 == 0)

    if (isMultOfFive && isMultOfThree) {
        print("FizzBuzz")
    } else if isMultOfThree {
        print("Fizz")
    } else if isMultOfFive {
        print("Buzz")
    } else {
        print(i)
    }
}