Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bonfire Algorithm Challenge: Where Do I Belong on javascript

Hello guys I am currently stuck on this algorithm challenge on FCC. This is what the challenge is all about:

Return the lowest index at which a value (second argument) should be inserted into an array (first argument) once it has been sorted. The returned value should be a number.

For example, getIndexToIns([1,2,3,4], 1.5) should return 1 because it is greater than 1 (index 0), but less than 2 (index 1).

Likewise, getIndexToIns([20,3,5], 19) should return 2 because once the array has been sorted it will look like [3,5,20] and 19 is less than 20 (index 2) and greater than 5 (index 1).

This is my code here:

function getIndexToIns(arr, num) {
    var getIndx;

    var newArr = arr.sort(function (a, b) {
        return (a - b);
    });

    for (i = 0; i < newArr.length; i++) {
        if (num > newArr[i]) {
            getIndx = newArr.indexOf(newArr[i]);
        }
    }

    return getIndx;
}

getIndexToIns([10, 20, 30, 40, 50], 35);

when I ran the code it worked but it isn't passing the test. Guys I need your help. Thanks

like image 798
Johnbosco Avatar asked Feb 28 '26 10:02

Johnbosco


2 Answers

The solutions proposed so far tend to follow literally the request of the problem: first sort the array, then find the index where to insert the number. That brings you to loop over the array twice. More if you have to clone the array. That is slow, even without considering all the garbage we end up creating ...

Can we do better? I think so.

How about "count how many numbers in the array are less or equal to the number to insert". This achieves the same goal but let's us do it looping only once over the array.

function getIndexToIns(arr, num) {
    return arr.reduce(function (c, x) { return x <= num ? c+1 : c }, 0);
}

console.log(getIndexToIns([10, 20, 30, 40, 50], 35)); // 3
console.log(getIndexToIns([20,3,5], 19)); //2 
console.log(getIndexToIns([1,2,3,4], 1.5)); //1
console.log(getIndexToIns([1,2,3,4], 1)); //1
console.log(getIndexToIns([1,2,3,4], 0)); //0

how about that?! twice as fast*, yay!

* it's probably not really twice as fast, if you have to be nitpicky about my claims...

EDIT

Actually I can do better. That ternary if introduces some branching in the code that bothers me. We could take advantage of javascript weirdness to avoid it

arr.reduce(function (c, x) { return c + (x <= num) }, 0)

why? because when combined with a numeric operation true is converted to 1 and false to 0
That removes the extra branching from the code so it's going to be slightly faster than the previous version ... And it would also be easier to unit test, if you care about that.

like image 196
alebianco Avatar answered Mar 02 '26 23:03

alebianco


You could iterate and check if the actual value is greater then the number. Then retuen the actual index. If no value match, then return the length of the array as new input index.

function getIndexToIns(arr, num) {
    var i;
    arr.sort(function(a, b){
        return a - b;
    });
    for (i = 0; i < arr.length; i++) {
        if (arr[i] > num) {
            return i;
        }
    }
    return arr.length;
}

console.log(getIndexToIns([10, 20, 30, 40, 50], 35)); // 3
console.log(getIndexToIns([1, 2, 3, 4], 1.5));        // 1
console.log(getIndexToIns([20, 3, 5], 19));           // 2
console.log(getIndexToIns([4, 3, 2, 1], 5));          // 4

Alternative version without using a method from the Array API

function getIndexToIns(array, value) {
    var i = array.length,
        p = 0;

    while (i--) {
        p += array[i] <= value;
    }
    return p;
}

console.log(getIndexToIns([10, 20, 30, 40, 50], 35)); // 3
console.log(getIndexToIns([1, 2, 3, 4], 1.5));        // 1
console.log(getIndexToIns([20, 3, 5], 19));           // 2
console.log(getIndexToIns([4, 3, 2, 1], 5));          // 4
like image 33
Nina Scholz Avatar answered Mar 02 '26 23:03

Nina Scholz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!