From dfbe8e06d7931ab0d0c7645c3f19a208d063b9b9 Mon Sep 17 00:00:00 2001 From: Quentin Cornier Date: Sun, 7 Apr 2024 14:49:47 +0200 Subject: [PATCH 1/3] Create mentoring.md for grains exercice in cpp Creating the guide for the solution of the grains exercise in cpp. Offering an imperative and a recursive solution for the first function and explaining how to do correctly the second function. --- tracks/cpp/exercises/grains/mentoring.md | 45 ++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 tracks/cpp/exercises/grains/mentoring.md diff --git a/tracks/cpp/exercises/grains/mentoring.md b/tracks/cpp/exercises/grains/mentoring.md new file mode 100644 index 000000000..7a002be93 --- /dev/null +++ b/tracks/cpp/exercises/grains/mentoring.md @@ -0,0 +1,45 @@ +# Mentoring + +## First function + +The first way to implement this function is to use a for loop : +```cpp +unsigned long long square(int indice) { + unsigned long long result = 1; + for (int i = 0; i < indice; i++) result *= 2; + return result; +} +``` +A cleaner way to do this is to use a recursive function : +```cpp +unsigned long long square(int indice) { + if (indice == 1) return 1; + else return square(indice - 1) * 2; +} +``` +This way, the code is shorter and in my mind, easier to read. + +## Second function +At first sight, we want to use the first function to do it easily : +```cpp +unsigned long long total() { + unsigned long long sum = 0; + for (int i = 1; i <= 64; i++) sum += square(i); + return sum; +} +``` +However with this solution, each time you call the function square with the indice i, you do i products. +In the following solution, you only do 64 products and by adding to the sum each time you multiply by 2 : +```cpp +unsigned long long total() { + unsigned long long total = 0; + unsigned long long square = 1; + + for (int k = 0; k < 64; k++) { + total += square; + square *= 2; + } + + return total; +} +``` From 793edd761e86c65767696054f397b2b6af1c0b8f Mon Sep 17 00:00:00 2001 From: Quentin Cornier Date: Sun, 7 Apr 2024 20:08:19 +0200 Subject: [PATCH 2/3] Update mentoring.md Changing indice to index Removing "cleaner" for the recursive method Adding the direct method for the first function --- tracks/cpp/exercises/grains/mentoring.md | 25 +++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/tracks/cpp/exercises/grains/mentoring.md b/tracks/cpp/exercises/grains/mentoring.md index 7a002be93..582b379ac 100644 --- a/tracks/cpp/exercises/grains/mentoring.md +++ b/tracks/cpp/exercises/grains/mentoring.md @@ -4,21 +4,32 @@ The first way to implement this function is to use a for loop : ```cpp -unsigned long long square(int indice) { +unsigned long long square(int index) { unsigned long long result = 1; - for (int i = 0; i < indice; i++) result *= 2; + for (int i = 0; i < index; i++) result *= 2; return result; } ``` -A cleaner way to do this is to use a recursive function : +Another good way to do this is to use a recursive function : ```cpp -unsigned long long square(int indice) { - if (indice == 1) return 1; - else return square(indice - 1) * 2; +unsigned long long square(int index) { + if (index == 1) return 1; + else return square(index - 1) * 2; } ``` This way, the code is shorter and in my mind, easier to read. +The last option and the more direct one is : +```cpp +unsigned long long square(int index) +{ + return 1ULL << (index - 1); +} +``` +This code use left bitshifting. Left bitshifting consists in adding 0 at the end of the binary writing of the number. + +If you do ```5 << 2```, you are taking 5, which is 101 in binary, and you shift the bits by 2, so you end up with 10100 and that equal to 20. + ## Second function At first sight, we want to use the first function to do it easily : ```cpp @@ -28,7 +39,7 @@ unsigned long long total() { return sum; } ``` -However with this solution, each time you call the function square with the indice i, you do i products. +However with this solution, each time you call the function square with the index i, you do i products. In the following solution, you only do 64 products and by adding to the sum each time you multiply by 2 : ```cpp unsigned long long total() { From cd0bc23a755a8f3f464841769a9000d4ef57e0f7 Mon Sep 17 00:00:00 2001 From: Quentin Cornier Date: Mon, 8 Apr 2024 09:09:52 +0200 Subject: [PATCH 3/3] Update mentoring.md removing space before colon adding a direct implementation for total adding common issues and suggestions section --- tracks/cpp/exercises/grains/mentoring.md | 41 ++++++++++++++++++------ 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/tracks/cpp/exercises/grains/mentoring.md b/tracks/cpp/exercises/grains/mentoring.md index 582b379ac..1e6d6f13b 100644 --- a/tracks/cpp/exercises/grains/mentoring.md +++ b/tracks/cpp/exercises/grains/mentoring.md @@ -1,8 +1,10 @@ # Mentoring -## First function +## Reasonable solutions -The first way to implement this function is to use a for loop : +### First function + +The first way to implement this function is to use a for loop: ```cpp unsigned long long square(int index) { unsigned long long result = 1; @@ -10,7 +12,7 @@ unsigned long long square(int index) { return result; } ``` -Another good way to do this is to use a recursive function : +Another good way to do this is to use a recursive function: ```cpp unsigned long long square(int index) { if (index == 1) return 1; @@ -19,7 +21,7 @@ unsigned long long square(int index) { ``` This way, the code is shorter and in my mind, easier to read. -The last option and the more direct one is : +The last option and the more direct one is: ```cpp unsigned long long square(int index) { @@ -28,10 +30,10 @@ unsigned long long square(int index) ``` This code use left bitshifting. Left bitshifting consists in adding 0 at the end of the binary writing of the number. -If you do ```5 << 2```, you are taking 5, which is 101 in binary, and you shift the bits by 2, so you end up with 10100 and that equal to 20. +If you do `5 << 2`, you are taking 5, which is 101 in binary, and you shift the bits by 2, so you end up with 10100 and that equal to 20. -## Second function -At first sight, we want to use the first function to do it easily : +### Second function +At first sight, we want to use the first function to do it easily: ```cpp unsigned long long total() { unsigned long long sum = 0; @@ -39,8 +41,8 @@ unsigned long long total() { return sum; } ``` -However with this solution, each time you call the function square with the index i, you do i products. -In the following solution, you only do 64 products and by adding to the sum each time you multiply by 2 : +However with this solution only works with a direct implementation of the first function, else each time you call the function square with the index i, you do i products. +In the following solution, you only do 64 products and by adding to the sum each time you multiply by 2: ```cpp unsigned long long total() { unsigned long long total = 0; @@ -54,3 +56,24 @@ unsigned long long total() { return total; } ``` +Moreover, this is also possible to use a direct implementation for this function: +```cpp +unsigned long long total() { + return ~0ULL; +} +``` +With this way we use the fact that a ULL is 64 bits long and we use the ~ to do the complement. + +## Common issues + +- Not using unsigned long long types +- Using ULLONG_MAX, for the second function, which works, however this is like returning directly the good number +- Using std::pow that implies conversion from float to int and could lead to errors mainly in the total function +- Hard coding the solution for the total + +## Common suggestions + +- Use the square function in total only if square use a direct implementation +- The optimal way is to use bitwise operations + +