**Swift Programming from Scratch**

The Swift Sandbox is integrated, making the exercises interactive. Read more about the book here.

**Chapter 7: Functions**

A function is a chunk of code that performs a specific task. Functions have a name that describes their purpose, that name is used to call the function to perform the task when needed. You can provide data to a function by sending parameters to it, and the function can give data back as result.

Let’s take a simple example:

```
func isOdd(number: Int) -> Bool {
if number % 2 == 1 {
return true
} else {
return false
}
}
isOdd(number: 1) // true
isOdd(number: 2) // false
isOdd(number: 3) // true
```

In the above example `isOdd`

is the name of the function, `number`

is the parameter and `Bool`

is the return type.

**Defining a function**

When you define a function, you can optionally define one or more named, typed values that the function takes as input (known as parameters), and/or a type of value that the function will pass back as output when it is done (known as its return type).

The general syntax for a function is:

**func** `name`

(`list of parameters`

) -> `return type`

{

`statements`

}

Some functions don’t return any values. In that case the syntax doesn’t have the arrow(->) and the return type.

**func** `name`

(`list of parameters`

) {

`statements`

}

**Functions with no parameters with no return value**

```
func sayHello() {
print("Hello!")
}
sayHello() // Hello!
```

**Functions with one parameter with no return value**

Parameters are followed by their type.

```
func sayHello(to name: String) {
print("Hello \(name)!")
}
sayHello(to: "Swift") // Hello Swift!
```

**Functions with one parameter and return value**

To add a return value to a function write `->`

after the list of parameter followed by the type of the result. Functions that return a value must do so using the `return`

keyword. When calling return inside a function the code execution will stop at that line – similar to the `break`

statement inside a loop.

```
func square(number: Int) -> Int {
return number * number
}
square(number: 1) // 1
square(number: 2) // 4
square(number: 3) // 9
```

**Functions with multiples parameters with no return value**

To declare multiple parameters use commas to separate them.

```
func count(from: Int, to: Int) {
for i in from...to {
print(i)
}
}
count(from: 5, to: 10)
// 5
// 6
// 7
// 8
// 9
// 10
```

Notice that the all parameters have the name in the function call. That is called the external parameter name. All parameters have an implicit external parameter name, the same as the local parameter name.

**Functions with multiples parameters and return value**

```
func sum(_ a: Int, _ b: Int) -> Int {
return a + b
}
print(sum(1, 2)) // 3
```

Notice that this time neither parameter appeared in the function call. This is because of the `_`

character in front of`a`

and `b`

. It this case `_`

means don’t give this parameter an external name. Remember this because you are going to use it in the exercises.

**External parameter names**

Sometimes it’s useful to name your parameters differently when you call a function.

For example:

```
func sayHello(name:String) {
print("Hello " + name + "!")
}
sayHello(name: "Batman")
// Hello Batman!
```

In this case it would have more sense name the parameter `to`

because then the function call would read`sayHello(to: "Batman")`

. But then the code inse the function would make less sense.

To do this you must define *external parameter names* for them. You can write external parameter names before the local name. All parameters have the external parameter name set to the local one by default. You can change it by writing a different name before it.

```
func sayHello(to name:String) {
print("Hello " + name + "!")
}
sayHello(to: "Batman")
// Hello Batman!
```

You can make a function ignore the external parameter name by writing `_`

in front of the parameter name:

```
func double(_ number: Int) -> Int {
return number * 2
}
```

External parameter names make your code clear. Don’t remove them unless you have to.

**Default Parameter Values**

You can define a default value for any parameter in a function definition. You do this by following the parameter definition with a `=`

sign and the value for that parameter. If a parameter has a default value set you can omit that parameter when calling the function. To keep things clean it’s recommended that you write all the parameters with default value at the end of the parameter list.

```
func countdown(from: Int, to: Int = 1) {
for i in (to...from).reversed() {
print(i)
}
}
countdown(from: 3)
// 3
// 2
// 1
countdown(from: 5, to: 3)
// 5
// 4
// 3
```

**In-Out Parameters**

Function parameters are constant by default, that means that you cannot change the value of a parameter inside a function. Trying to change the value of a parameter will result in a compile error.

If you want the function to change the value of a parameter and you want those changes to persist after the function call, define the parameter as an `inout`

parameter.

Keep in mind that you can only pass variables as in-out parameters. You cannot pass a constant or a literal value, because they cannot be changed. You have to write an ampersand (`&`

) in front of the variable name when calling the function. That will indicate that the variable can be modified by the function.

```
func double(number: inout Int) {
number = number * 2
}
var n = 10
double(number: &n)
print(n) // 20
```

Quick tip

If you want to change the value of a parameter and those changes don’t need to be reflected outside the function then you can just declare a variable with the same name:func printNumber(after number: Int) { var number = number number += 1 print(number) } printNumber(after: 2) // 3

**7.1 Min**

Write a function named `min2`

that takes two `Int`

values, `a`

and `b`

, and returns the smallest one. Use `_`

to ignore the external parameter names for both `a`

and `b`

.

`func min2(_ a: Int, _ b: Int) -> Int`

Function call:

`min2(1,2)`

Output:

```
1
```

Function call:

`min2(10,5)`

Output:

```
5
```

You can have multiple `return`

statements in one function.

```
func min2(_ a: Int, _ b: Int) -> Int {
if a < b {
return a
} else {
return b
}
}
```

**7.2 Last Digit**

Write a function that takes an `Int`

and returns it’s last digit. Name the function `lastDigit`

. Use `_`

to ignore the external parameter name.

`func lastDigit(_ number: Int) -> Int`

Function call:

`lastDigit(12345)`

Output:

```
5
```

Function call:

`lastDigit(1000)`

Output:

```
0
```

Function call:

`lastDigit(123)`

Output:

```
3
```

Use the modulo(`%`

) operator.

```
func lastDigit(_ number: Int) -> Int {
return number % 10
}
```

**7.3 First Numbers**

Write a function named `first`

that takes an `Int`

named `N`

and returns an array with the first `N`

numbers starting from `1`

. Use `_`

to ignore the external parameter name.

`func first(_ N: Int) -> [Int]`

Function call:

`first(3)`

Output:

```
[1, 2, 3]
```

Function call:

`first(1)`

Output:

```
[1]
```

Function call:

`first(10)`

Output:

```
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

Use the `append`

function on arrays to create the required result.

```
func first(_ N: Int) -> [Int] {
var numbers:[Int] = []
for number in 1...N {
numbers.append(number)
}
return numbers
}
```

**7.4 Countdown**

Write a function named `countdown`

that takes a number `N`

. The function should print the numbers from `N`

to `1`

with a one second pause in between and then write `GO!`

in the end. To make the computer wait for one second call the`sleep`

function from the standard library. The `sleep`

function takes one parameter, the number of seconds to sleep.

In order to use the `sleep`

function you will need to import the Foundation framework.

```
import Foundation
// now you can use the sleep function
sleep(1) //will wait for one second before executing the next line
```

`func countdown(_ N: Int)`

```
import Foundation
// your code here
```

Function call:

`coutdown(3)`

Output:

```
3
2
1
GO!
```

```
import Foundation
func countdown(_ N: Int) {
var i = N
while i > 0 {
print(i)
sleep(1)
i -= 1
}
print("GO!")
}
```

**7.5 Prime Numbers**

Implement the following functions. The `divides`

function returns `true`

if `a`

is divisible by `b`

and `false`

otherwise. The `countDivisors`

function should use the `divides`

function to return the number of divisors of `number`

. The`isPrime`

function should use the `countDivisors`

function to determine if `number`

is prime.

`func divides(_ a: Int, _ b: Int) -> Bool`

`func countDivisors(_ number: Int) -> Int`

`func isPrime(_ number: Int) -> Bool`

Examples:

```
divides(3, 2) // false - 3 is not divisible by 2
divides(6, 3) // true - 6 is divisible by 3
countDivisors(2) // 2 - 1 and 2
countDivisors(6) // 4 - 1, 2, 3 and 6
countDivisors(12) // 6 - 1, 2, 3, 4, 6 and 12
isPrime(2) // true
isPrime(3) // true
isPrime(10) // false
isPrime(13) // true
```

Function call:

`isPrime(2)`

Output:

```
true
```

Function call:

`isPrime(3)`

Output:

```
true
```

Function call:

`isPrime(10)`

Output:

```
false
```

Function call:

`isPrime(13)`

Output:

```
true
```

The `isPrime`

function can be implemented in a single line using the `countDivisors`

function.

```
func divides(_ a: Int, _ b: Int) -> Bool {
return a % b == 0
}
func countDivisors(_ number: Int) -> Int {
var cnt = 0
for i in 1...number {
if divides(number, i) {
cnt += 1
}
}
return cnt
}
func isPrime(_ number: Int) -> Bool {
return countDivisors(number) == 2
}
```

**7.6 First Primes**

Using `isPrime`

write a function named `printFirstPrimes`

that takes a parameter named `count`

of type `Int`

that prints the first `count`

prime numbers.

`func printFirstPrimes(_ count: Int)`

Function call:

`printFirstPrimes(3)`

Output:

```
2
3
5
```

Function call:

`printFirstPrimes(10)`

Output:

```
2
3
5
7
11
13
17
19
23
29
```

Use the `isPrime`

function from the previous exercise.

```
func printFirstPrimes(_ count: Int) {
var i = 2
var printed = 0
while printed < count {
if isPrime(i) {
print(i)
++printed
}
++i
}
}
```

**7.7 Repeat Print**

Implement a function named `repeatPrint`

that takes a string `message`

and a integer `count`

as parameters. The function should print the `message`

`count`

times and then print a newline.

`func repeatPrint(message: String, count: Int)`

Function call:

`repeatPrint("+", 10)`

Output:

```
++++++++++
```

Function call:

`repeatPrint(message: "<->", count: 3)`

Output:

```
<-><-><->
```

Don’t forget about the newline at the end.

```
func repeatPrint(message: String, count: Int) {
for i in 1...count {
print(message, terminator: "")
}
print("")
}
```

**7.8 Reverse**

Write a function named `reverse`

that takes an array of integers named `numbers`

as a parameter. The function should return an array with the numbers from `numbers`

in reverse order.

`func reverse(_ numbers: [Int]) -> [Int]`

Function call:

`reverse([1, 2, 3])`

Output:

```
[3, 2, 1]
```

Function call:

`reverse([1, 2, 1, 2, 1, 2])`

Output:

```
[2, 1, 2, 1, 2, 1]
```

```
func reverse(_ numbers: [Int]) -> [Int] {
var reversed: [Int] = []
for number in numbers {
reversed.insert(number, at: 0)
}
return reversed
}
```

**7.9 Sum**

Write a function named `sum`

that takes an array of integers and returns their sum.

`func sum(_ numbers: [Int]) -> Int`

Function call:

`sum([1, 2, 3])`

Output:

```
6
```

Function call:

`sum([1, 1, 1, 1, 1])`

Output:

```
5
```

```
func sum(_ numbers: [Int]) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum
}
```

**7.10 Parse number**

Write a function named `parse(digit:)`

that takes a string with one character as parameter. The function should return `-1`

if the input is not a digit character and the digit otherwise.

```
parse(digit: "1") // 1
parse(digit: "3") // 3
parse(digit: "a") // -1
```

`func parse(digit: String) -> Int`

Use a string of digits `let digits = "0123456789"`

.

First we check if the given string is a number, if it is not we return `-1`

. Next we initialize our result to `0`

. For each character in the given string we multiply the result by 10, shifting all digits with 1 position to the left and we add the result of `parseDigit`

for the current digit.

```
func parse(digit: String) -> Int {
let digits = "0123456789"
var result = 0
for character in digits.characters {
var d = "\(character)"
if d == digit {
return result
}
result += 1
}
return -1
}
```

Using the `parse(digit:)`

function you can determine if a string of length one is a digit or not. Implement a function named `isNumber`

that takes an arbitrary length string and return `true`

if the string contains only digits and `false`

otherwise. Note that empty strings should not be considered numbers.

```
isNumber("a") // false
isNumber("1") // true
isNumber("1234567890") // true
isNumber("12345abc") // false
isNumber("") // false
```

`func isNumber(_ string: String) -> Bool`

If the string we’re given is empty we return `false`

otherwise we iterate through all the characters in our string, if any of these characters returns `-1`

from our `parseDigit`

function we return `false`

. If none of them return `-1`

from parseDigit it means that all characters in our string are digits and we return `true`

```
func isNumber(_ string: String) -> Bool {
if string.characters.count == 0 {
return false
}
for character in string.characters {
if parse(digit: "\(character)") == -1 {
return false
}
}
return true
}
```

Using the `isNumber`

and `parse(digit:)`

functions, write a function named `parse(number:)`

that takes a string and returns it’s values as an integer or `-1`

if the string does not contain only digits.

```
parse(number: "1") // 1
parse(number: "54321") // 54321
parse(number: "1337") // 1337
parse(number: "12cd") // -1
```

`func parse(number: String) -> Int`

First we check if the given string is a number, if it is not we return `-1`

. Next we initialize our result to `0`

. For each character in the given string we multiply the result by 10, shifting all digits with 1 position to the left and we add the result of `parse(digit:)`

for the current digit.

```
func parse(number: String) -> Int {
if isNumber(number) != true {
return -1
}
var result = 0
for character in number.characters {
var digit = "\(character)"
result = result * 10 + parse(digit: digit)
}
return result
}
```

**7.11 Time Difference**

Write a function named `timeDifference`

. It takes as input four numbers that represent two times in a day and returns the difference in minutes between them. The first two parameters `firstHour`

and `firstMinute`

represent the hour and minute of the first time. The last two `secondHour`

and `secondMinute`

represent the hour and minute of the second time. All parameters should have external parameter names with the same name as the local ones.

```
func timeDifference(firstHour: Int,
firstMinute: Int,
secondHour: Int,
secondMinute: Int) -> Int
```

Function call:

`timeDifference(firstHour: 12, firstMinute: 3, secondHour: 13, secondMinute: 10)`

Output:

```
67
```

Function call:

`timeDifference(firstHour: 8, firstMinute: 10, secondHour: 17, secondMinute: 30)`

Output:

```
560
```

You’ll have to handle the case when the difference between minutes is less than `0`

.

```
func timeDifference(firstHour: Int,
firstMinute: Int,
secondHour: Int,
secondMinute: Int) -> Int {
var hourDifference = secondHour - firstHour
var minuteDifference = secondMinute - firstMinute
if minuteDifference < 0 {
hourDifference -= 1
minuteDifference += 60
}
return hourDifference * 60 + minuteDifference
}
```

**7.12 Correct Pairs**

Write a function named `verify`

that takes a string `expression`

of open and closed parentheses (`(`

, `)`

) and returns`true`

if they are correctly paired and `false`

otherwise.

`func verify(expression: String) -> Bool`

Function call:

`verify(expression: "()")`

Output:

```
true
```

Function call:

`verify(expression: "((")`

Output:

```
false
```

Function call:

`verify(expression: "(())")`

Output:

```
true
```

Function call:

`verify(expression: "()()")`

Output:

```
true
```

Function call:

`verify(expression: "(()))")`

Output:

```
false
```

Function call:

```
verify(expression: ")(")
```

Output:

```
false
```

Keep track of how many open parentheses you’ve encountered and how many closed parentheses.

In a correct pairing the number of closed parentheses you encounter can never be greater than the number of open parentheses.

```
func verify(expression: String) -> Bool {
var open = 0
var closed = 0
for char in expression.characters {
var character = "\(char)"
if character == "(" {
open += 1
} else {
closed += 1
if closed > open {
return false
}
}
}
return open == closed
}
```

**7.13 Mario**

Mario uses energy points to walk and jump. He can jump maximum `maxJump`

meters up or down. You have the height of each 1 meter portion of a level in the `heights`

array. Determine if Mario can finish the level and how much energy he needs to do it. Mario uses 1 energy point to walk one meter and `2 * jumpHeight`

energy points to `jumpHeight`

meters. Write a function named `levelCost`

that takes `heights`

and `maxJump`

as parameters and returns `-1`

if Mario cannot finish the level or the total energy cost that he would need to finish the level.

In the beginning Mario will be on the first 1 meter section of the level and the `heights`

array will always have more than one element. All heights have a value greater or equal to 1.

```
levelCost(heights: [1, 1, 2, 2, 5, 2, 1, 1], maxJump: 3) // 19
// 1 point to walk
// 2 to jump from 1 to 2
// 1 point to walk
// 6 to jump from 2 to 5
// 6 to jump from 5 to 2
// 2 to jump from 2 to 1
// 1 point to walk
levelCost(heights: [1, 1, 3, 1, 1], maxJump: 2) // 10
// 1 point to walk
// 4 to jump from 1 to 3
// 4 to jump from 3 to 1
// 1 point to walk
levelCost(heights: [1, 1, 8, 1], maxJump: 5) // -1
// Mario cannot jump from 1 to 8
```

`func levelCost(heights: [Int], maxJump: Int) -> Int`

Think about how you can compute the energy required for a single step.

```
func levelCost(heights: [Int], maxJump: Int) -> Int {
var totalEnergy = 0
var lastHeight = 0
for height in heights {
if lastHeight == 0 {
lastHeight = height
} else {
var jumpHeight = lastHeight - height
if jumpHeight < 0 {
jumpHeight = -jumpHeight
}
if jumpHeight > maxJump {
return -1
}
if jumpHeight == 0 {
totalEnergy += 1
} else {
totalEnergy += 2 * jumpHeight
}
lastHeight = height
}
}
return totalEnergy
}
```

**7.14 Queue**

A queue is a data structure that can perform two operations:

**push**which takes a value and adds it at the end of the queue**pop**which returns the value from the start of the queue and removes it from the queue

Your task is to implement the `push`

and `pop`

operations. The most simple way to represent a queue is using an array. Here are some example operations.

```
// here we define an empty queue
var queue: [Int] = []
// add 1 in the queue
push(1, &queue) // queue = [1]
// add 2 in the queue
push(2, &queue) // queue = [1, 2]
// pop the first element
pop(&queue) // 1, queue = [2, 3]
// add 3 in the queue
push(3, &queue) // queue = [2, 3]
// pop the first element
pop(&queue) // 2, queue = [3]
// pop the first element
pop(&queue) // 3, queue = []
// pop the first element
pop(&queue) // returns nil because there are no elements in the queue
// queue = []
```

The `push`

function should take two parameters, the `number`

and the `queue`

as an inout parameter.

`func push(_ number: Int, _ queue: inout [Int])`

The `pop`

function should take `queue`

as an inout parameter and return the first number from the queue after removing it. If the queue is empty it should return nil – the result type should be an optional integer(`Int?`

).

`func pop(_ queue: inout [Int]) -> Int?`

For the `pop`

function you’ll have to retrieve the first element in the queue.

```
func push(_ number: Int, _ queue: inout [Int]) {
queue.append(number)
}
func pop(_ queue: inout [Int]) -> Int? {
var result = queue.first
if queue.count > 0 {
queue.remove(at: 0)
}
return result
}
```

**7.15 Stack**

A stack is a data structure that can perform three operations:

**push**adds a value on the top of the stack**top**returns the value from the top of the stack**pop**returns the value from the top of the stack and removes it from there

Your task is to implement the `push`

, `top`

and `pop`

operations. The most simple way to represent a stack is using an array. Here are some example operations.

```
var stack: [Int] = []
push(1, &stack) // stack = [1]
push(2, &stack) // stack = [1, 2]
pop(&stack) // 2, stack = [1]
push(3, &stack) // stack = [1, 3]
pop(&stack) // 3, stack = [1]
pop(&stack) // 1, stack = []
pop(&stack) // returns nil because there are no elements in the stack
// stack = []
```

`push`

takes two parameters, the `number`

that will be pushed and the `stack`

as an inout parameter.

`func push(_ number: Int, _ stack: inout [Int])`

`top`

takes one parameter, the `stack`

, and returns the value of the top element or nil if the stack is empty – the result type should be and optional integer(`Int?`

)

`func top(_ stack: [Int]) -> Int?`

`pop`

takes the `stack`

as an inout parameter, and returns the value of the top element after it removes it. If the`stack`

is empty it should return nil – the result type should be and optional integer(`Int?`

)

`func pop(_ stack: inout [Int]) -> Int?`

You’ll have to get the last element from the stack for the `top`

operation.

```
func push(_ number: Int, _ stack: inout [Int]) {
stack.append(number)
}
func top(_ stack: [Int]) -> Int? {
if stack.count == 0 {
return nil
}
return stack[stack.count - 1]
}
func pop(_ stack: inout [Int]) -> Int? {
var result = top(stack)
if stack.count > 0 {
stack.remove(at: stack.count - 1)
}
return result
}
```

**Swift Programming from Scratch**

Read more about the book here.

Feel free to ask any questions in the comments bellow.

Hello. Question, regarding the solution for 7.6. Does it make a difference whether we write the ++ before or after printed and/or i? Thanks

Just a few notes I made along the way

Time Difference –

This seems unnecessary AFAIK :

if minuteDifference < 0 {

hourDifference -= 1

minuteDifference += 60

}

Mario –

There’s a typo, it’s 10, not 14, as explained in the comments of the exemple.

levelCost(heights: [1, 1, 3, 1, 1], maxJump: 2) // 14

// 1 point to walk

// 4 to jump from 1 to 3

// 4 to jump from 3 to 1

// 1 point to walk

Queue –

Typos :

• push witch takes a value and adds it at the end of the queue

• push witch returns the value from the start of the queue and removes it from the queue

The pop function should the queue as an inout parameter

if minuteDifference < 0 { hourDifference -= 1 minuteDifference += 60 }from 10:45 to 11:10 that branch is usedThank you for the typos

I’m not saying it’s not used, but that you don’t need it.

Having a negative minuteDifference does not break your code.

With your example :

firstHour = 10

firstMinute = 45

secondHour = 11

secondMinute = 10

hourDifference = 11 – 10 = 1

minuteDifference = 10 – 45 = -35

returned value :

hourDifference * 60 + minuteDifference = 1 * 60 + (-35) = 60 – 35 = 25.

Might I humbly suggest that this would be a slightly better solution to 7.2:

func lastDigit(number: Int) -> Int {

return abs(number) % 10

}

hello,

Solution 7.8

func reverse(numbers: [Int]) -> [Int] {

var reversed: [Int] = []

for i in number {

reversed.insert(i, atIndex: 0)

}

return reversed

}

I’m confused why the array appears in reversed. from what i read we iterate reverse and input in the empty array, starting at index 0, how come it appears reverse if we never changed the order of array.

thanks for explaining

The code iterates the numbers array. Reversed is initially empty. At each iteration we insert the current element at index 0 (at the front of the array) in reversed.

Let’s say numbers = [1, 2, 3, 4] reversed will be [1], [2,1], [3,2,1], [4,3,2,1] respectively at each iteration.

thanks for clarifying !

solution 7.12

func verifyParentheses(expression: String) -> Bool {

var open = 0

var closed = 0

for scalar in expression.unicodeScalars {

var character = “\(scalar)”

if character == “(” {

++open

} else {

++closed

if closed > open {

return false

}

}

}

return open == closed

}

code

//if character == “(” {

// ++open

does this syntax mean for ever “(” increase “var open” by 1 ?

also

//if closed > open {

// return false

even in the case where closed < open it returns false, how come swift returns false? this isn't mentioned anywhere in the code

also

// return open == closed

does the word "return" represent something? is this code a shorthand for

// if open == closed { return true}

this really intrigues me since it's not the first time i see a solution with the word "return" pop up at the end and it holds a value when nothing was ever assigned to it.

please explain, really confused :$

For 7.5 you don’t consider 1 as prime, since your condition in ‘isPrime’ equals to 2 and 1 con only be divided by itself.

1 is not prime.

The more you know! You are totally correct!, As I’m reading some math papers explaining why. Thanks for your quick response.

C style of ‘For’ loop is going to be deprecated in future versions of SWIFT, how are we going to write it to behave in decrements instead of increments?

for i in 5.stride(to: 1, by: -1) {

print(i)

}

// 5, 4, 3, 2

for i in 5.stride(through: 1, by: -1) {

print(i)

}

// 5, 4, 3, 2, 1

Hello,

For exercise 7.11 Time Difference,

wouldn’t be simpler in one line:

return (secondHour * 60 + secondMinute) – (firstHour * 60 + firstMinute)

Your solution is also correct and it might look simpler for most coders. As far as I’ve noticed new coders are a bit intimidated by long expressions like that one. Code that has 1-2 instructions per line is easier to understand.

I’m getting an error on 7.13. It says my function definition is not correct, but it is exactly like the one on this page.