Search code examples
javascriptsearchbinary-search

How to switch between item value in an array and item index to calculate a variable?


My program calculates how many days were above the specified temperature by the user. I am using a binary search and need to calculate a mid point but I am having trouble switching between the array item value and the array index. When the value is above the mid I set the start to the mid + 1 but the mid then gets reassigned to its previous value. How should I do this? I have tried doing

var mid = Math.floor(janMax(end) - janMax(start) / 2);

it won't work.

This is my binary search function:

function binarySearchAbove(end, value){
    var start = janMax[0];
    var end = janMax[30];
    var count = "";
    console.log(end);//53, works
    var value = listInput.value;

    while (value <= end){
        var average = Math.floor(janMax.length / 2);
        var mid = janMax[average];
        console.log(average);
        console.log(mid);//44
        console.log(start);//45

        for (i = 0; i < janMax.length; i++){
            if(value == janMax[i]){
            break;
            console.log(i);//gives correct value    
            }
        }

        if (value < mid){
            start++;
            console.log(start);//37

        }   else if (value > mid){
            start = mid + 1;
            console.log(start);//45

        }
        if (value == mid || value == start){
            count = janMax.length - i;//0
            console.log(i);//gives 31
            alert("There were " + count + " days above " + value + " degrees.");
            break;
        }   

        if (value <= start){
            alert("Every day was above " + value + " degrees.");
            break;

        }   else if (value >= end){
            alert("There were no days above " + value + " degrees.");
            break;
        }
    }
}

var janMax = [36, 37, 38, 38, 39, 39, 39, 39, 40, 40, 40, 41, 42, 44, 44, 44, 46, 46, 47, 47, 47, 47, 47, 48, 48, 49, 49, 50, 50, 53, 53];


Solution

  • I mean the simplest answer would be this, but that's not a binary search as you wanted it:

    const janMax = [36, 37, 38, 38, 39, 39, 39, 39, 40, 40, 40, 41, 42, 44, 44, 44, 46, 46, 47, 47, 47, 47, 47, 48, 48, 49, 49, 50, 50, 53, 53];
    
    function searchAbove(value) {
        return janMax.reduce((count, curr) => curr > value ? count + 1 : count, 0);
    }
    
    console.log(searchAbove(44));

    But this would be a implementation for the binary search:

    var janMax = [36, 37, 38, 38, 39, 39, 39, 39, 40, 40, 40, 41, 42, 44, 44, 44, 46, 46, 47, 47, 47, 47, 47, 48, 48, 49, 49, 50, 50, 53, 53];
    
    function binarySearchAbove(value) {
      if (value < janMax[0]) {
        alert("Every day was above " + value + " degrees.");
        return;
      } else if (value >= janMax[janMax.length - 1]) {
        alert("There were no days above " + value + " degrees.");
        return;
      }
    
      let count = 0;
    
      function countHigherValues(values) {
        if (values.length == 0) {
          return;
        }
    
        const midIndex = Math.floor(values.length / 2);
    
        if (value > values[midIndex]) {
          countHigherValues(values.slice(midIndex));
        } else {
          let currIndex = midIndex;
          while (currIndex >= 0 && values[currIndex] > value) {
            currIndex--;
          }
    
          currIndex++;
          while (currIndex < values.length && values[currIndex] >= value) {
            if (values[currIndex] > value) {
              count++;
            }
    
            currIndex++;
          }
        }
      }
    
      countHigherValues(janMax);
    
      alert("There were " + count + " days above " + value + " degrees.");
    }
    
    binarySearchAbove(43);
    binarySearchAbove(59);
    binarySearchAbove(29);