Following on from our explanation around Project Euler Problem 1, we were using Arithmetic Series to sum the number of terms in a range, incrementing by an integer n. The formula to do so looks like this:
We can think of a_1 and a_n as the first and last terms of the arithmetic series we’re summing. The key task, then, is figuring out how to determine these directly from the range.
For any step size k, the first term a_1 is simply the first multiple of k, which is k itself. The last term a_n is the largest number within the range that is still divisible by k.
For example, consider the range 1 to 10 with a step size of 3. The multiples of 3 are 3, 6, and 9. Here, a_1 = 3 and a_n = 9.
So the general problem then becomes: given any upper bound, how do we systematically determine the last value in the range that is divisible by k, and therefore define the full arithmetic series from just the range itself? That's effectively what this code is doing:
upper_limit = 9
multiple = 3
n = upper_limit // multiple
a_1 = multiple
a_n = (upper_limit // multiple) * multiple
s_n_n1 = n * (a_1 + a_n) // 2
s_n_n1
n(upper_limit // multiple) just says give me the number of times (terms) in the series. a_1 has to be the multiple itself (the first multiple of 3, which in this case is 3 since our range starts at 1), and a_n (upper_limit // multiple) * multiple) calculates the last term in the series by saying that if we have 3 terms in the series and we increment by 3 (and assume the first term of the series is the multiple) the last term of the series has to be 3 x 3 = 9. So for any range, we now have a method to get back to a_1 and a_n.
A note on the Arithmetic Series Equation
It also helps the application of the equation to understand its derivation. If we take a series that spans from a_1 to a_n, we get:
Writing the series backwards (which seems like a crazy thing to do, but bear with me), we then get:
Thus, if we sum each pair of terms together in each series, we get
We notice that each term pairs naturally with another term from the opposite end of the sequence. Because each step forward increases by a fixed amount, and each step backward decreases by the same amount, every pair sums to the same value.
Let's try this in practice to drive the point home. Let's take the series:
3, 6, 9
Here, a_1 is 3, and a_n = 9. As in the description above, we can write the sum forwards:
S = 3 + 6 + 9
or backwards:
S = 9 + 6 + 9
In both cases, we arrive at 18 as the sum. Now, however, let's add these together, term by term:
2S = (3 + 9) + (6 + 6) + (9 + 3)
Since we are adding the series to itself, we should get 2S, which we do (18 + 18 = 36). But, more importantly, we can see something important -- each term sums to the same number:
3 + 9 = 12
6 + 6 = 12
9 + 3 = 12
So instead of thinking of individual numbers, we can just generalise the summation to:
2S = 3 x (a_1 + a_n)
because there are 3 terms, and each term pair sums to a_1 + a_n (12). To generalise further, we can just use n as a placeholder for the number of terms in the series, to then arrive at:
2S = n x (a_1 + a_n)
And finally, we divide by 2 to get the sum of the original series:
S = (n x (a_1 + a_n))/ 2
If you've found this useful or interesting, please consider subscribing to be notified via email when I publish articles to this site. I publish long-form, in-depth articles on ML, AI, and Data Science every two weeks or so, as well as practical business-oriented coding problems, like this one.