Dario K
Dario K

Reputation: 336

How to iterate over an array multiple times without repeating summed elements

I am trying to solve this problem but I don't know why I can't pass all test cases. I need some help and explanation, how can I count some array (in this example: variable s) multiple times and not repeat the same elements that I already summed.

Problem description:

Lily has a chocolate bar that she wants to share it with Ron for his birthday. Each of the squares has an integer on it. She decides to share a contiguous segment of the bar selected such that the length of the segment matches Ron's birth month and the sum of the integers on the squares is equal to his birth day. You must determine how many ways she can divide the chocolate.

Consider the chocolate bar as an array of squares, s=[2,2,1,3,2]. She wants to find segments summing to Ron's birth day, d=4 with a length equalling his birth month, m=2. In this case, there are two segments meeting her criteria: [2,2] and [1,3].

Function Description

Complete the birthday function in the editor below. It should return an integer denoting the number of ways Lily can divide the chocolate bar.

birthday has the following parameter(s):

s: an array of integers, the numbers on each of the squares of chocolate, d: an integer, Ron's birth day, m: an integer, Ron's birth month

My code:

function birthday(s, d, m) {
    let bars = 0;

    if (m !== 1) {
        s.reduce((acc, val) => (acc+val) === d ? ++bars : bars)
    } else {
        bars = 1;
    }

    return bars;
}

Some cases:

My code works with this:

This can be found on HackerRank > Practice > Algorithms > Implementation

Upvotes: 2

Views: 1530

Answers (3)

kmoser
kmoser

Reputation: 9273

Here's an easy to understand way with nested loops:

function birthday(s, d, m) {
    var matches = 0; // Total matches found

    // Look at chunks starting a position 0. Last chunk can't be m spots past end of array, so last chunk starts at 1 + s.length - m:
    for ( let i=0; i < 1 + s.length - m; i++ ) {
        var sum = 0; // What this chunk sums to

        // Sum up the values of this chunk:
        for ( let j=0; j < m; j++ ) {
            sum += s[i+j];
        }
        if ( sum === d ) { // Does this chunk sum to d?
            matches++; // Yes!
        }
    }

    return matches;
}

Upvotes: 1

hgb123
hgb123

Reputation: 14891

You just have to slice the array with the sliced length of m, and then compare that to d

As slice doc:

The slice() method returns a shallow copy of a portion of an array into a new array object selected from start to end (end not included) where start and end represent the index of items in that array. The original array will not be modified.

For example:

s = [1, 2, 1, 3, 2]
m = 2 
d = 3

// We loop through s with index stop at s.length - m + 1 for slice to be in correct range

// Slices:
i=0: [1, 2] -> sum=3 -> res=0+1=1
i=1: [2, 1] -> sum=3 -> res=1+1=2
i=2: [1, 3] -> sum=4 -> do nothing
i=4: [3, 2] -> sum=5 -> do nothing
 

Below is a worked solution

function birthday(s, d, m) {
  let res = 0
  const sum = (arr) => arr.reduce((acc, el) => acc + el, 0)

  for (let i = 0; i < s.length - m + 1; i++) {
    if (sum(s.slice(i, i + m)) === d) {
      res++
    }
  }
  
  return res
}

enter image description here

Upvotes: 1

Seif Miehiar
Seif Miehiar

Reputation: 31

Whenever you are looping over an array to get the summation or do a mathematical equation on it and you have to remove that specific element that you already calculated, You can use one of these built in function to remove an element from an array using a specific index. Array.prototype.slice() && Array.prototype.splice()

Upvotes: 1

Related Questions