This article is part of my #100DaysOfCode and #100DaysOfBlogging challenge. R1D7


Today I am solving the Difference of Squares of the PHP track on Exercism.

Exercism offers its users learning new programming languages through exercises with the valuable feedback of mentors. It currently has 50 different language tracks like C#, Go, Kotlin, TypeScript and many others. Head over to Exercism to join.

Introduction

The source of this exercise is Problem 6 of the Euler project.

The sum of the squares of the first ten natural numbers is,

12 + 22 + ... + 102 = 385

The square of the sum of the first ten natural numbers is,

(1 + 2 + ... + 10)2 = 552 = 3025

Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 − 385 = 2640.

Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.

First step

Usually I start by downloading the tests, creating the required file (in this case difference-of-squares.php) and if possible, provide the required function(s) with a correct signature. Since I already know from the introduction section, the difference() function returns the difference of squareOfSum() and sumOfSquares(). So, I go ahead and write that down. I’m starting off with the following lines.

<?php

declare(strict_types = 1);

function squareOfSum(int $number) : int
{
    return 0;
}

function sumOfSquares(int $number) : int
{
    return 0;
}

function difference(int $number) : int
{
    return squareOfSum($number) - sumOfSquares($number);
}

I run the tests. As expected, they are all failing. But it confirms to me, that there are no syntax error or errors of undefined functions. So far, so good.

Next, I like to break down the exercise. I can see, that three functions are required. I start with the first one squareOfSum(). I focus on one test at a time. I comment out all tests except the first and implement its described feature.

Square of Sum

The description of squareOfSum() is straight forward. I’m thinking of first creating an array of numbers starting from 1 to n. range() seems to be perfect for that. Next, I need to calculate the sum. Since I already have an array, I use array_sum(). And finally, I square the sum and return it.

<?php

function squareOfSum(int $number) : int
{
    $sum = array_sum(range(1, $number));
    return $sum * $sum;
}

To validate my implementation, I uncomment all tests asserting the result of squareOfSum() and run the tests. Success! 👍

Sum of squares

The second function is doing the same in a different order. My first thought is, if I could abstract any functionality from the first function which I could use in the second. They only have the range() call in common. It would be overkill to abstract that into a separate function. So, I leave it as it is and return to the implementation.

Again, I need a range. This time however I need to square the element values. A simple callback should do with the help of array_map() and followed by array_sum().

<?php

function sumOfSquares(int $number) : int
{
    $array = array_map(
        static function (int $number) {
            return $number * $number;
        },
        range(1, $number)
    );

    return array_sum($array);
}

I uncomment all the remaining tests and run them. Again, successfully. 🙌

Clean-up

Before submitting my solution, I run code analysis tools in PhpStorm and check for error or warnings. Usually this is very helpful. It helps me to (1) learn more about PHP and how I could improve and (2) show potential errors which I did not see.

In this case Psalm is throwing 4 errors:

Scanning files...
Analyzing files...

ERROR: InvalidReturnType - difference-of-squares\difference-of-squares.php:5:37 - The declared return type 'int' for squareOfSum is incorrect, got 'float|int'
function squareOfSum(int $number) : int


ERROR: InvalidReturnStatement - difference-of-squares\difference-of-squares.php:8:12 - The type 'float|int' does not match the declared return type 'int' for squareOfSum
    return $sum * $sum;


ERROR: InvalidReturnType - difference-of-squares\difference-of-squares.php:11:38 - The declared return type 'int' for sumOfSquares is incorrect, got 'int|float'
function sumOfSquares(int $number) : int


ERROR: InvalidReturnStatement - difference-of-squares\difference-of-squares.php:20:12 - The type 'int|float' does not match the declared return type 'int' for sumOfSquares
    return array_sum($array);


------------------------------
4 errors found
------------------------------

Checks took 0.37 seconds and used 29.759MB of memory
Psalm was able to infer types for 100% of the codebase

But I am not sure how Psalm can get a float value from adding and square an integer value? So, I leave it as it is and submit my solution.

My submitted solution

<?php

declare(strict_types = 1);

function squareOfSum(int $number) : int
{
    $sum = array_sum(range(1, $number));
    return $sum * $sum;
}

function sumOfSquares(int $number) : int
{
    $array = array_map(
        static function (int $number) {
            return $number * $number;
        },
        range(1, $number)
    );

    return array_sum($array);
}

function difference(int $number) : int
{
    return squareOfSum($number) - sumOfSquares($number);
}

Mentoring

Within the next few days a mentor will review my code and provide feedback. So far, I have been very blessed with good reviewers who took their time to give suggestions and refer to other resources. This is very helpful.

Sometimes the feedback is not as pleasant as I was hoping. 😄 I then take a step back and take my time before reading it again. This time with an open mind to see, what the mentor is trying to show me. It has always been a great learning experience for me.

As soon as a solution gets accepted, you can share your solution with the community and inspect what others have submitted. This is alxvery helpful and oftentimes an eye opener.