From aa246604136d4cc9a06008f3d5cb7e30cbc65a4f Mon Sep 17 00:00:00 2001 From: Gonzalo Diaz Date: Wed, 17 May 2023 23:07:40 -0400 Subject: [PATCH 1/2] New helper: isPalindrome. Check if the number complies with the property of being written equally from left to right as from right to left. --- src/helpers/index.ts | 1 + src/helpers/isPalindrome.test.ts | 12 ++++++++++++ src/helpers/isPalindrome.ts | 4 ++++ 3 files changed, 17 insertions(+) create mode 100644 src/helpers/isPalindrome.test.ts create mode 100644 src/helpers/isPalindrome.ts diff --git a/src/helpers/index.ts b/src/helpers/index.ts index d377da46..4b0594aa 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -1,2 +1,3 @@ export { divisors } from './divisors'; export { isPrime } from './prime'; +export { isPalindrome } from './isPalindrome'; diff --git a/src/helpers/isPalindrome.test.ts b/src/helpers/isPalindrome.test.ts new file mode 100644 index 00000000..d2a366a6 --- /dev/null +++ b/src/helpers/isPalindrome.test.ts @@ -0,0 +1,12 @@ +import { isPalindrome } from './isPalindrome'; + +describe('number is Palindrome', () => { + it('some numbers are palindrome', () => { + expect.assertions(4); + + expect(isPalindrome(1)).toBe(true); + expect(isPalindrome(131)).toBe(true); + expect(isPalindrome(1221)).toBe(true); + expect(isPalindrome(123454321)).toBe(true); + }); +}); diff --git a/src/helpers/isPalindrome.ts b/src/helpers/isPalindrome.ts new file mode 100644 index 00000000..b4e5be6d --- /dev/null +++ b/src/helpers/isPalindrome.ts @@ -0,0 +1,4 @@ +export const isPalindrome = (n: number): boolean => + n.toString().split('').reverse().join('') === n.toString(); + +export default { isPalindrome }; From c9eeb8f36abf6c6a4759ade327c5d88aa89893f8 Mon Sep 17 00:00:00 2001 From: Gonzalo Diaz Date: Wed, 17 May 2023 23:08:02 -0400 Subject: [PATCH 2/2] Problem 0004: solved. --- src/helpers/index.ts | 3 ++ src/problem0004.test.ts | 32 +++++++++++++++++++ src/problem0004.ts | 69 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 src/problem0004.test.ts create mode 100644 src/problem0004.ts diff --git a/src/helpers/index.ts b/src/helpers/index.ts index 4b0594aa..7f5061b0 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -1,3 +1,6 @@ +type nullable = T | null | undefined; + export { divisors } from './divisors'; export { isPrime } from './prime'; export { isPalindrome } from './isPalindrome'; +export { nullable }; diff --git a/src/problem0004.test.ts b/src/problem0004.test.ts new file mode 100644 index 00000000..1a89ec57 --- /dev/null +++ b/src/problem0004.test.ts @@ -0,0 +1,32 @@ +/** + * Largest palindrome product + * + * https://projecteuler.net/problem=4 + * + * A palindromic number reads the same both ways. + * The largest palindrome made from the product of two 2-digit + * numbers is 9009 = 91 × 99. + * + * Find the largest palindrome made from the product of two 3-digit numbers. + */ + +import logger from './logger'; + +import { problem0004 } from './problem0004'; + +describe('problem 0004', () => { + it('problem 0004 solution found', () => { + expect.assertions(1); + + const solutionFound = 906609; + + const bottom = 111; + const top = 999; + + const calculated = problem0004(bottom, top); + + logger.info(`PROBLEM 0004 solution found: ${calculated}`); + + expect(calculated).toBe(solutionFound); + }); +}); diff --git a/src/problem0004.ts b/src/problem0004.ts new file mode 100644 index 00000000..57480baf --- /dev/null +++ b/src/problem0004.ts @@ -0,0 +1,69 @@ +/** + * Largest palindrome product + * + * https://projecteuler.net/problem=4 + * + * A palindromic number reads the same both ways. + * The largest palindrome made from the product of two 2-digit + * numbers is 9009 = 91 × 99. + * + * Find the largest palindrome made from the product of two 3-digit numbers. + */ + +/// //////////////////////////////////////////////////////////////////////////// +// NOTES ABOUT THE SOLUTION: +// This solution cycles to test all pairs of factors between 111 and 999 that meet the condition of generating a palindrome and saves the largest found. +// I think there must be another optimal solution to avoid testing all cases +// cutting the loop around the largest factor pair +// That's why I thought about doing the loop from highest to lowest. +/// //////////////////////////////////////////////////////////////////////////// + +/// //////////////////////////////////////////////////////////////////////////// + +import logger from './logger'; + +import { nullable, isPalindrome } from './helpers/index'; + +function problem0004(_bottom: number, _top: number): nullable { + let i; + let j; + let foundi; + let foundj; + let foundPalindrome; + + // Find all cases + let cycles = 0; + + i = _top; + while (i >= _bottom) { + j = i; + while (j >= _bottom && (!foundj || j >= foundj)) { + cycles += 1; + + if (isPalindrome(j * i)) { + logger.debug(`FOUND: ${i} x ${j} = ${j * i} is Palindrome`); + + if (!foundPalindrome || i * j > foundPalindrome) { + foundi = i; + foundj = j; + foundPalindrome = i * j; + } + } else { + // console.log(`FOUND: ${i} x ${j} = ${j * i} is NOT Palindrome`); + } + + j -= 1; + } + + i -= 1; + } + + logger.info( + `Problem 0004 Largest Palindrome => ${foundi} 𝗑 ${foundj} = ${foundPalindrome} in ${cycles} cycles` + ); + + return foundPalindrome; +} + +export default problem0004; +export { problem0004 };