DEV Community

Lukas Müller
Lukas Müller

Posted on

My functional approach to HackerRank's 'Mini-Max Sum' challenge

Problem: Given five positive integers, find the minimum and maximum values that can be calculated by summing exactly four of the five integers. Then print the respective minimum and maximum values as a single line of two space-separated long integers.

Link: https://www.hackerrank.com/challenges/mini-max-sum/problem

My thought process went like this:

1) The function will receive an array of 5 inputs and should calculate the sum of 4 of those. Thus, 1 value of the array should be removed (either the highest or the lowest). We can use Math.max and Math.min to find out which value needs to be removed.

2) The array could have identical values, in that case only one of them should be removed. For this, we can use Array.indexOf which only returns the index of the first match it finds.

3) To remove the value from the array, we can use Array.splice. Unfortunately, that function mutates the original array. Due to the fact that we need to find the minimum sum AND the maximum sum, we need to touch the array twice, thus mutation is not an option. And aside from that, mutation is against the rules of functional programming.

Is there a different Array function I could have used for this?

4) To get the sum of the other values in the array, we can use Array.reduce.

5) The processes of getting the minimum and maximum sum are equal exact for one function (Math.max for minimum and Math.min for maximum (opposite because the functions are used to remove the number that should be excluded from the calculation)). This calls for a curried function, meaning a function that receives as a parameter either Math.max or Math.min and returns the function that calculates the minimum or maximum sum, depending on the passed function.

This resulted in the following solution:

const removeNumberFromArrayAndSumRest = removalFn => arr => {
    const tmp = [].concat(arr);
    const toBeRemoved = removalFn(...tmp);
    tmp.splice(tmp.indexOf(toBeRemoved), 1);
    return tmp.reduce((a, b) => a + b);
}

// Complete the miniMaxSum function below.
const miniMaxSum = (arr) => {    
    console.log(`${removeNumberFromArrayAndSumRest(Math.max)(arr)} ${removeNumberFromArrayAndSumRest(Math.min)(arr)}`);
}
Enter fullscreen mode Exit fullscreen mode

This might not be the best approach, but I'm pretty satisfied with it. Functional programming really is a marvel.

Does anyone here use HackerRank? What's your approach to this challenge?

Top comments (1)

Collapse
 
vonheikemen profile image
Heiker

I see your single purpose reduce and raise you a reduce that does a bunch of stuff (just for fun).

const add = (a, b) => a + b;
const print = ([a, b]) => console.log(`${a} ${b}`);
const repeat = (num, item) => Array.from({ length: num }, () => item);

const three_ops = ([first, ...rest]) => rest.reduce(
  (state, value) => [
    state[0], 
    Math.max(state[0], value),
    Math.min(state[0], value),
    add(state[3], value)
  ],
  repeat(4, first)
);

function miniMaxSum(arr) {
  const [,max,min,sum] = three_ops(arr);

  return [
    sum - max,
    sum - min
  ];
}

print(miniMaxSum([1,3,5,7,9]));
Enter fullscreen mode Exit fullscreen mode

Kids, don't do this at home.