From 3866e8b43183077cffa4dc94aa9ceb592aa8c148 Mon Sep 17 00:00:00 2001 From: Daniel Dorado Date: Sat, 15 Oct 2022 17:31:47 -0500 Subject: [PATCH 1/2] [CREATE] Problem 28 solution for Project Euler --- Project-Euler/Problem028.js | 35 +++++++++++++++++++++++++++ Project-Euler/test/Problem028.test.js | 17 +++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 Project-Euler/Problem028.js create mode 100644 Project-Euler/test/Problem028.test.js diff --git a/Project-Euler/Problem028.js b/Project-Euler/Problem028.js new file mode 100644 index 0000000000..79b3637df1 --- /dev/null +++ b/Project-Euler/Problem028.js @@ -0,0 +1,35 @@ +/** + * Problem 28 - Number spiral diagonals + * + * @see {@link https://projecteuler.net/problem=28} + * + * Starting with the number 1 and moving to the right in a clockwise direction a 5 by 5 spiral is formed as follows: + * + * 21 22 23 24 25 + * 20 07 08 09 10 + * 19 06 01 02 11 + * 18 05 04 03 12 + * 17 16 15 14 13 + * + * It can be verified that the sum of the numbers on the diagonals is 101. + * What is the sum of the numbers on the diagonals in a 1001 by 1001 spiral formed in the same way? + * + * @author ddaniel27 + */ + +function problem28 (dim) { + if (dim % 2 === 0) { + throw new Error('Dimension must be odd') + } + if (dim < 1) { + throw new Error('Dimension must be positive') + } + + let result = 1 + for (let i = 3; i <= dim; i += 2) { + result += (4 * i * i) + 6 * (1 - i) // Calculate sum of each dimension corner + } + return result +} + +export { problem28 } diff --git a/Project-Euler/test/Problem028.test.js b/Project-Euler/test/Problem028.test.js new file mode 100644 index 0000000000..ad99654598 --- /dev/null +++ b/Project-Euler/test/Problem028.test.js @@ -0,0 +1,17 @@ +import { problem28 } from '../Problem028.js' + +describe('checking number spiral diagonals', () => { + it('should be invalid input if number is negative', () => { + expect(() => problem28(-3)).toThrowError('Dimension must be positive') + }) + it('should be invalid input if number is not odd', () => { + expect(() => problem28(4)).toThrowError('Dimension must be odd') + }) + test('if the number is equal to 5 result should be 101', () => { + expect(problem28(5)).toBe(101) + }) + // Project Euler Condition Check + test('if the number is equal to 1001 result should be 669171001', () => { + expect(problem28(1001)).toBe(669171001) + }) +}) From 3418cdd9a6e749e8d9a8e37edb65c3d69233fc78 Mon Sep 17 00:00:00 2001 From: Daniel Dorado Date: Sun, 16 Oct 2022 08:03:55 -0500 Subject: [PATCH 2/2] [UPDATE] Added an explanation for the formula used in the algorithm --- Project-Euler/Problem028.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Project-Euler/Problem028.js b/Project-Euler/Problem028.js index 79b3637df1..e55f31b959 100644 --- a/Project-Euler/Problem028.js +++ b/Project-Euler/Problem028.js @@ -27,6 +27,24 @@ function problem28 (dim) { let result = 1 for (let i = 3; i <= dim; i += 2) { + /** + * Adding more dimensions to the matrix, we will find at the top-right corner the follow sequence: + * 01, 09, 25, 49, 81, 121, 169, ... + * So this can be expressed as: + * i^2, where i is all odd numbers + * + * Also, we can know which numbers are in each corner dimension + * Just develop the sequence counter clockwise from top-right corner like this: + * First corner: i^2 + * Second corner: i^2 - (i - 1) | The "i - 1" is the distance between corners in each dimension + * Third corner: i^2 - 2 * (i - 1) + * Fourth corner: i^2 - 3 * (i - 1) + * + * Doing the sum of each corner and simplifing, we found that the result for each dimension is: + * sumDim = 4 * i^2 + 6 * (1 - i) + * + * In this case I skip the 1x1 dim matrix because is trivial, that's why I start in a 3x3 matrix + */ result += (4 * i * i) + 6 * (1 - i) // Calculate sum of each dimension corner } return result