# Chapter 7 - Worked Exercises

{% tabs %}
{% tab title="Exercise 1" %}
Create a function prototype for a function called `max`, that accepts an integer array and its length, and returns the largest element in the array.

Implement the function.&#x20;

```cpp
int main() {
    int numbers[10] = {1, 4, 13, 0, 7, 3, 20, 8, 2, 4};
    std::cout << "The maximum is " << max(numbers, 10) << std::endl;
    // The above should print 20
}
```

The function should return `-1` if the array is empty.
{% endtab %}

{% tab title="Solution" %}

```cpp
int max(int numbers[], int length) {
    int largest = -1;
    for (int i = 0; i < length; i++) {
        // Remember ternary statements? 
        largest = numbers[i] > largest ? numbers[i] : largest;
    }
    return largest;
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Exercise 2" %}
Create a program that sums all the digits in a number:

```cpp
Enter a number: 342
The sum of all the digits in 342 is 9. 
```

You should create **two implementations** of this program, one using a **for-loop or while loop** to perform the summing, and another using a **recursive function**.
{% endtab %}

{% tab title="Solution 1" %}

```cpp
#include <iostream>

int main() {
    int number;
    std::cout << "Please enter a number: ";
    std::cin >> number;
    
    int sum = 0;
    
    while (number > 0) {
        sum += number % 10;  // The right-most digit of `number`
        number = number / 10;  // Remove the right-most digit of `number`
    }
    
    std::cout << "The sum of all the digits in " << number << " is " << sum << std::endl;

}
```

{% endtab %}

{% tab title="Solution 2" %}

```cpp
#include <iostream>

int sumAllDigits(int number) {
    if (number == 0) {
        return 0;
    }
    return number % 10 + sumAllDigits(number / 10);
}

int main() {
    int number;
    std::cout << "Please enter a number: ";
    std::cin >> number;
    
    int sum = sumAllDigits(number);
    
    std::cout << "The sum of all the digits in " << number << " is " << sum << std::endl;
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Exercise 3" %}
The factorial function (symbol: **!**) is the product of all positive integers less than or equal to the number provided.

* `5!` is `5 * 4 * 3 * 2 * 1`
* `10!` is `10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1`

Create a function, `factorial`, that computes the factorial of a number.&#x20;

Your first implementation should use a **for-loop or while-loop**, and your second implementation should use **recursion**.
{% endtab %}

{% tab title="Solution 1" %}

```cpp
// This multiplies from 1 to n
int factorial(int n) {
    int result = 1;
    for (int i = 1; i <= n; i++) {
        result *= i;
    }
    return result;
}

// To do it in reverse, from n to 1
int factorial(int n) {
    int result = 1;
    while (n > 0) {
        result *= n;
        n--;
    }
}
```

{% endtab %}

{% tab title="Solution 2" %}

```cpp
int factorial(int n) {
    if (n == 1) {
        return 1;
    }
    return n * factorial(n - 1);
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Exercise 4" %}
Below we have an example of a program that helps people split a restaurant bill equally amongst the people present:

```cpp
#include <iostream>
#include <vector>

int main() {
    // Ask how many items 
    int numberOfItems = 0;
    std::cout << "How many items were ordered? ";
    std::cin >> numberOfItems; 
    
    // Ask for the price of each item 
    std::vector<int> itemPrices;
    int itemPrice = 0;
    for (int i = 0; i < numberOfItems; i++) {
        std::cout << "Please enter the price of Item " << i;
        std::cin >> itemPrice;
        itemPrices.push_back(itemPrice);
    }
    
    // Sum up all our prices 
    int totalCost = 0;
    for (int price: itemPrices) {
        totalCost += price;
    }
    
    // Ask how many people were present
    int numberOfPeople = 0;
    std::cout << "How many people should the bill be split by? ";
    std::cin >> numberOfPeople;
    
    float costPerPerson = totalCost / numberOfPeople;
    std::cout << "Each person should pay: " << costPerPerson << std::endl;
}
```

Your job is to improve the readability of this program, by abstracting some of code logically into separate functions.&#x20;

**Bonus**: Can you also account for edge cases? What if the user enters `0` number of people? Should negative prices be allowed? Can we modify the program to allow decimals for the price of each item?&#x20;
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Exercise 5" %}

## Task 1&#x20;

Previously we've learned that functions have a name, can accept zero or more arguments, but can only return a single value.&#x20;

So far we've learned that we can return multiple values using a certain method, what is this method?&#x20;

Using this method, create a function called `calculateAreaAndVolume` that takes a float value corresponding to the `length` of the edge of a cube, calculates and returns the total **area** and **volume** of the cube.&#x20;

## Task 2

For each of the following, create a lambda that fits each of the function descriptions. Use sensible and descriptive variables that fit the function description.&#x20;

**Bonus**: Declare explicitly the function pointer type instead of using `auto`

### Example

Accepts 2 integer values, and returns the sum of the two.&#x20;

```cpp
auto sum = [](int a, int b){ return a + b; };
// Example:
int number = sum(3, 5); // `number` should be 8
```

1. Accepts 3 integer values, and returns the largest value out of the 3.&#x20;
2. Accepts a `Day` enum value corresponding to days of the week, returns `true` if the day is a weekday, `false` otherwise.&#x20;
3. Accepts no parameters, but **captures** from the current scope a string variable called `name`,  and prints the greeting `"Hello there, name!"`
4. Accepts no parameters, but **captures** from the current scope a vector of integers called `numbers`, and sets each element in the vector to 0.&#x20;

## Task 3

For each of the following, qualitatively describe the lambda.&#x20;

### Example&#x20;

```cpp
auto concatenante = [](std::string first, std::string second) {
    return first + second;
}
```

A lambda function called `concatenate` that captures nothing, accepts two string parameters, and returns the concatenation of the two parameters.

1. ```cpp
   auto exists = [](std::vector<int> numbers, int numberToFind) {
       for (auto number: numbers) {
           if (number == numberToFind) {
               return true;
           }
       }
       return false;
   };
   ```
2. ```cpp
   auto accumulate = [method](std::vector<int> numbers) {
       if (method == "sum") {
           int sum = 0;
           for (auto number: numbers) {
               sum += number;
           }
           return sum;
       } 
       if (method == "multiply") {
           int sum = 1;
           for (auto number: numbers) {
               sum *= sum;
           }
           return sum;
       }
       return -1;
   };
   ```
3. ```cpp
   auto haveMoney = [moneyInWallet, moneyInBank, moneyInDrawer](){
       return moneyInWallet || moneyInBank || moneyInDrawer;
   };
   ```
4. ```cpp
   auto calculateAreaAndVolume = [&area, &volume] (int x) {
       area = x * x * 6;  // A cube has 6 sides 
       volume = x * x * x; 
   };
   ```

## Task 4

We learned that **function pointers** allow us to store functions into variables. This also means that we can use these variables as part of arguments to other functions, in other words, passing a function into a function.

Consider the following program:

```cpp
#include <string>
#include <iostream>

void greetHello(std::string name) {
    std::cout << "Hello, " << name << "!" << std::endl;
}

void greetSalutations(std::string name) {
    std::cout << "Salutations, " << name << "!" << std::endl;
}

int main() {
    std::cout << "What is your name? ";
    cin >> std::string name;
}
```

Usually we would call the following functions as `greetHello(name)` or `greetSalutations(name)`, but instead your task is to create another function called `apply` that takes **two** arguments:

* A function pointer argument for a void function that takes a single string argument&#x20;
* A string argument

And calls the function referred to by the function pointer, with the string argument provided.&#x20;

For example, calling:

```cpp
apply(greetHello, "Andrew"); 
```

Would result in `"Hello, Andrew!"` being printed to the console.&#x20;

### Solution&#x20;

The syntax for using function pointers as function parameters is similar to the syntax for function pointers themselves:

```cpp
<return_type>(*<parameter_name>)(<func_pointer_parameter_type>, ...)
```

```cpp
void apply(void(*functionToCall)(std::string), std::string name) {
    functionToCall(name);
}
```

{% endtab %}
{% endtabs %}
