Solving Code Challenges: The MinMaxSum Problem.

Solving Code Challenges: The MinMaxSum Problem.

Hey.

I have finally gotten out of a self-created rut to begin writing again, and whilst this bit of information may not be pertinent to this article, it is somewhat imperative to start this series (yes, series! yay us!) with "the why" this particular piece exists in the first place.

Background

Over the past couple of weeks, I have been tinkering about what to write. I largely settled on pieces about new stuff I have been learning in Java and Golang. Ultimately, I began considering writing about solving technical interview code challenges since I had been interviewing recently so here we go. Throughout this series, I will alternate between HackerRank and LeetCode problems with varying degrees of difficulty.

Now that we have the backstory out of the way, this first article in this series is a code challenge from HackerRrank.

Problem

The image above describes what the problem is, we are presented with an array of numbers and are expected to sum up four of the five numbers in the array, sorting the addition operation by index.

When the addition operation is complete, we are then required to log the smallest (min) and largest (max) numbers (MinMax) as the solution to the problem. The second part of the problem – which shows a sample input and its expected output – is represented in the image below.

Solution

We are presented with a function minMaxSum that receives an array of positive integers arr described in the example above. I approach solving this problem by first declaring a variable savedArr and assigning an empty array to it to avoid mutating the original array arr.

function miniMaxSum(arr) {
  let savedArr = [];
  for (let i = 0; i < arr.length; i++) {
      if (i === 0) {
          const minOne = arr.slice(1)
          const reduceMinOne = minOne.reduce(reduceArr)
          savedArr = [...savedArr, reduceMinOne]
      }
      // rest of code...
    }
}

I instantiate a for loop that runs the addition operation for as long as I need.

In the example, the first addition operation is carried out without the first element of the given array arr (I have attached a photo below to help you remember).

I remove the first element of the array (arr.slice(1)) and assign it to a variable minOne , then I sum up the values of the new array minOne using the array.reduce() method and assign it to a new variable reduceMinOne .

const reduceMinOne = minOne.reduce(reduceArr)

Taking a closer look at reduceMinOne , there is a strange-looking dude on that line called reduceArr that's yet to be introduced, so let's meet the good ol' chap.

function reduceArr(acc, value) {
      return acc + value;
  }

reduceArr is a simple function that accepts two parameters (acc, value) and returns the sum of both parameters.

Now that we understand what reduceArr does, it becomes easier to understand how it is applied to the minOne array like so: const reduceMinOne = minOne.reduce(reduceArr). I'd explain the array.reduce() method but it is beyond the scope of this article, but you can read more about that bit here.

Remember savedArr ? I assigned an empty array to this variable, now let's update savedArr, shall we?

savedArr = [...savedArr, reduceMinOne]

What the line above does is to "open up" the savedArr variable using the spread operator (you can read more about the javascript spread operator here) and inserting the reduceMinOne value into it.

Intermission...

Phew! We have been writing code for a while now so let's take a break and stare at a random gif on the internet.

via GIPHY

Solution [Cont'd]

Okay, now that the first iteration of the loop has been handled, we need to deal with the rest, to do so, I introduced two new variables minTwo and arrRest.

function miniMaxSum(arr) {
  let savedArr = [];
  for (let i = 0; i < arr.length; i++) {
      if (i === 0) {
          const minOne = arr.slice(1)
          const reduceMinOne = minOne.reduce(reduceArr)
          savedArr = [...savedArr, reduceMinOne]
      }
        // new block of code
         else {
          const minTwo = arr.slice(i + 1)
          const arrRest = arr.slice(0, i)
          const combinedArr = arrRest.concat(minTwo)
          const reduceMinRest = combinedArr.reduce(reduceArr)
          savedArr = [...savedArr, reduceMinRest]
      }
      // rest of code...
    }
}

To better understand variables minTwo and arrRest, let's have a second look at the example.

Points 2-5 expect us to run through the addition operation of the array, removing elements by index as we progress down the length of the array. So when I introduced const minTwo = arr.slice(i+1), I removed the first i element(s) (plus 1) where i = number of iterations. I have highlighted an explanation below so it's clearer.

// Example
var arr = [1, 2, 3, 4, 5]
// if i == 0
arr.slice(i) => // [2, 3, 4, 5]
arr.slice(i + 1) => // [3, 4, 5]

const arrRest = arr.slice(0, i) begins the slice operation from index 0 and ends at index i, returns a new array without including the element at index i.

// Example
var arr = [1, 2, 3, 4, 5]
// if i == 0
arr.slice(i + 1) => // [3, 4, 5]
arr.slice(i, 0) => // [1]

There are two more variables I introduced, combinedArr and reduceMinRest.

const combinedArr = arrRest.concat(minTwo)

The simple line of code above combines (yeah, I know!) both variables arrRest and minTwo into one array, positioning the value of arrRest in front of the new array combinedArr.

reduceMinRest uses the reducer function from earlier to find the sum of the elements in the combinedArr like so: const reduceMinRest = combinedArr.reduce(reduceArr).

Then, I update the savedArr array with the value from reduceMinRest like so: savedArr = [...savedArr, reduceMinRest]

Alright, we're almost there. To arrive at the solution required, we must sort through savedArr. Sorting helps us position the values in the array in ascending order.

function miniMaxSum(arr) {
  let savedArr = [];
  for (let i = 0; i < arr.length; i++) {
      if (i === 0) {
          const minOne = arr.slice(1)
          const reduceMinOne = minOne.reduce(reduceArr)
          savedArr = [...savedArr, reduceMinOne]
      }
      else {
          const minTwo = arr.slice(i+1)
          const arrRest = arr.slice(0, i)
          const combinedArr = arrRest.concat(minTwo)
          const reduceMinRest = combinedArr.reduce(reduceArr)
          savedArr = [...savedArr, reduceMinRest]
      }
      // new block of code
      if (savedArr.length === arr.length) {
          const sortArr = savedArr.sort()
          const min = sortArr.shift()
          const max = sortArr.pop()

          // solution
          console.log(min, max)
      }
  }

Before I begin the sort operation, I first check to ensure there is no overflow and I have the exact number of expected values in savedArr like so: if (savedArr.length === arr.length). I have also introduced three new variables: sortArr, min, and max.

sortArr sorts the array in ascending order using the sort() method while min returns the value in front of the array which by definition is the minimum sum obtained from the addition operation performed on the original array arr and max returns the value at the end of the array which is the maximum sum obtained from the addition operation performed on the original array arr.

Running the code against the sample test case shows that the code produces the expected output with the sample input from the example.

Result

Submitting the code against the hidden test cases also shows that it passes and all is right in the world.

Postscript

I may have omitted to take into account certain constraints as I solved this, if you have a much better way of solving this problem, feel free to shoot me your answer(s). I'd love to take a look.

Cheers!