Skip to content

Added BasicPrefixSum algorithm and tests #1786

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions PrefixSum/BasicPrefixSum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Computes the prefix sum (cumulative sum) of an array of numbers.
* For example, given [1, 2, 3], returns [1, 3, 6].
*
* @param {number[]} arr - The input array of numbers.
* @returns {number[]} - The prefix sum array.
* @throws {TypeError} - If input is not an array of numbers.
*/
function basicPrefixSum(arr) {
// Validate input: must be an array of numbers
if (!Array.isArray(arr) || !arr.every((x) => typeof x === 'number')) {
throw new TypeError('Input must be an array of numbers')
}

const prefix = []
// Use reduce to calculate cumulative sum and store in prefix array
arr.reduce((acc, val, index) => {
prefix[index] = acc + val // Store current sum at index
return prefix[index] // Pass current sum to next iteration
}, 0)
return prefix
}

// Export the function for use in other modules
module.exports = basicPrefixSum
22 changes: 22 additions & 0 deletions PrefixSum/test/BasicPrefixSum.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import basicPrefixSum from '../BasicPrefixSum'

describe('basicPrefixSum', () => {
it('computes correct prefix sums for normal arrays', () => {
expect(basicPrefixSum([1, 2, 3, 4])).toEqual([1, 3, 6, 10])
expect(basicPrefixSum([0, 0, 0])).toEqual([0, 0, 0])
expect(basicPrefixSum([-1, 5, -3])).toEqual([-1, 4, 1])
expect(basicPrefixSum([100])).toEqual([100]) // single element array
})

it('returns an empty array for empty input', () => {
expect(basicPrefixSum([])).toEqual([])
})

it('throws TypeError for invalid inputs', () => {
expect(() => basicPrefixSum('not an array')).toThrow(TypeError)
expect(() => basicPrefixSum([1, 2, 'x'])).toThrow(TypeError)
expect(() => basicPrefixSum([{}, 3])).toThrow(TypeError)
expect(() => basicPrefixSum(null)).toThrow(TypeError)
expect(() => basicPrefixSum(undefined)).toThrow(TypeError)
})
})
4 changes: 2 additions & 2 deletions Recursive/SubsequenceRecursive.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
* A Subsequence is sequence obtained by deleting some or no elements without changing the order of elements
* Example: Given a string = "abcd"
* 1. "abc" is a subsequence
* 2. "abd" is a subsequence
* 2. "acd" is a subsequence
* 3. But "ba" is not a subsequence (because order is changed)
*
* What is lexicographical order?
* In simple terms, lexicographical order is dictionary order.
* Example: Given a string = "abcd"
* 1. "abc" will come before "abcd".
* 2. "abd" will come before "ac".
* 2. "acd" will come before "ac".
*
* References for meaning of subsequence & lexicographical:
* https://en.wikipedia.org/wiki/Subsequence
Expand Down
16 changes: 9 additions & 7 deletions String/AlphaNumericPalindrome.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
/**
* @function alphaNumericPalindrome
* @description alphaNumericPalindrome should return true if the string has alphanumeric characters that are palindrome irrespective of special characters and the letter case.
* @description alphaNumericPalindrome should return true if the string has alphanumeric characters that form a palindrome,
* regardless of special characters and letter case.
* @param {string} str the string to check
* @returns {boolean}
* @see [Palindrome](https://en.wikipedia.org/wiki/Palindrome)
* @example
* The function alphaNumericPalindrome() receives a string with varying formats
* like "racecar", "RaceCar", and "race CAR"
* like "racecar", "RaceCar", and "race CAR".
* The string can also have special characters
* like "2A3*3a2", "2A3 3a2", and "2_A3*3#A2"
* like "2A3*3a2", "2A3 3a2", and "2_A3*3#A2".
*
* But the catch is, we have to check only if the alphanumeric characters
* are palindrome i.e remove spaces, symbols, punctuations etc
* and the case of the characters doesn't matter
* form a palindrome, i.e., remove spaces, symbols, punctuation, etc.
* The case of the characters doesn't matter.
*/
const alphaNumericPalindrome = (str) => {
if (typeof str !== 'string') {
throw new TypeError('Argument should be string')
}

// removing all the special characters and turning everything to lowercase
// Remove all non-alphanumeric characters and convert to lowercase
const newStr = str.replace(/[^a-z0-9]+/gi, '').toLowerCase()

const midIndex = newStr.length >> 1 // x >> y = floor(x / 2^y)

for (let i = 0; i < midIndex; i++) {
if (newStr.at(i) !== newStr.at(~i)) {
// ~n = -(n + 1)
// ~n = -(n + 1), used to get characters from the end
return false
}
}
Expand Down
Loading