website-copy
website-copy copied to clipboard
[dart/difference-of-squares] Create mentoring.md
added mentoring notes for difference of squares
Do we really recommend the "manual" approach where numbers from 1 to n are generated and summed up?
There's a direct and much more efficient solution, and I think that's what the last paragraph in the instructions is all about ("You are not expected to discover an efficient solution to this yourself from first principles; research is allowed, indeed, encouraged. Finding the best algorithm for the problem is a key skill in software engineering.")
At least for me the core of this exercise is finding the closed formulas for squareOfSum() and sumOfSquares().
How do other tracks solve this exercise? Or how did you solve it?
The question of "How do other tracks solve this exercise" is easy to answer, as you can look in each tracks repository and find their solution in each of the files.
For each track that has the exercise you will find the solution in:
<language>/exercises/practice/difference-of-squares/.meta/example.*
A ~~good~~ efficient solution in Python would look like this.
I don't know Dart at all but I guess a ~~good~~ efficient solution could look similar to this:
import "dart:math" show pow;
class DifferenceOfSquares {
/// Calculate the square of the sum of 1 .. [n].
///
/// See https://en.wikipedia.org/wiki/Triangular_number
int squareOfSum(int n) => pow((n + 1) * n ~/ 2, 2) as int;
/// Calculate the sum of the squares 1^2 .. [n]^2.
///
/// See https://en.wikipedia.org/wiki/Square_pyramidal_number
int sumOfSquares(int n) => n * (n + 1) * (2 * n + 1) ~/ 6;
/// Calculate the difference between the square of the sum and the sum of the squares.
int differenceOfSquares(int n) => squareOfSum(n) - sumOfSquares(n);
}
import "dart:math" show pow;
class DifferenceOfSquares {
int squareOfSum(int input) => pow(_sum(input), 2).toInt();
int sumOfSquares(int input) => _range(input).map((i) => pow(i, 2).toInt()).reduce((r, i) => r + i);
int differenceOfSquares(int input) => squareOfSum(input) - sumOfSquares(input);
num _sum(int input) => input * (input + 1) ~/ 2;
List<int> _range(int length) => new List<int>.generate(length, (i) => i + 1);
}
This is how the example.dart looks currently, and it iterates, rather than using the formula that can be used.
In a discussion two or three years ago I was told that the example solution from the .meta directory is not necessarily the best (easiest to read, most idiomatic, most efficient) solution, it's more like proof that the exercise can be solved, that it's possible to pass the tests.
I just wanted to comment that an efficient implementation exists and to draw attention to the last paragraph of the instructions, IMHO they clearly hint to such an efficient implementation.
But I have no skin in this game, I'm neither a Dart mentor nor do I know what Dart programmers would consider idiomatic. I'm fine with whatever you guys decide for these Dart mentoring notes.
In a discussion two or three years ago I was told that the example solution from the
.metadirectory is not necessarily the best (easiest to read, most idiomatic, most efficient) solution, it's more like proof that the exercise can be solved, that it's possible to pass the tests.
This is true for this exercise, if this is a practice exercise and not a concept exercise. I think that concept exercises should have an exemplar solution. I think, also, that there is the difference of that specific file being named, for practice, example.ext1, and for concept exercises, exemplar.ext1.
1: replacing, of course, the ext for the proper extension.
@smanookian do you feel like making changes to the notes based on the discussion above?