4

I have a sorted Array that contains numbers. I want to be able to check if this Array(or similar Array), contains 5 numbers in consecutive order.

NOTE: Array may contain duplicate and double digit numbers.

I am trying this, but failing epically.

var array = [1,3,5,7,7,8,9,10,11]
var current = null;
var cnt = 0;
for (var i = 0; i < array.length; i++) {
    if (array[i] != current) {
        if (cnt > 4) {
            return true;
        }
        current = array[i];
        cnt = 1;
    } else {
        cnt++;
    }

}
if (cnt > 4) {
    return true;
}

}
5
  • means can you give a sample input and expected answer. Commented Apr 15, 2015 at 4:26
  • What have you tried? My approach to this would be something along the lines of: iterate through the array, store the current value, if the next value is the same as the current, increment a counter. If they are different, set the counter back to 0. Commented Apr 15, 2015 at 4:26
  • find the content in this article :geeksforgeeks.org/check-if-array-elements-are-consecutive Commented Apr 15, 2015 at 4:33
  • is this defined inside a function? Not sure where return true would go, or how you would see the result. Also, cnt will only increase once, when it hits the two 7s Commented Apr 15, 2015 at 4:57
  • By "consecutive", what do you mean? In your sample data, the numbers or not "consecutive", they are merely monotonically increasing. Are duplicates counted in the five in a row, or skipped for counting purposes? Commented Apr 15, 2015 at 6:09

7 Answers 7

3

An iterative, straightforward approach would be:

var should_be_true = [1,3,5,7,7,8,9,10,11];
var should_be_false = [1,3,5,7,9,11,13,15,17];

var testArray = function(array) {
    var conseq = 1;
    for (var idx = 1; idx < array.length ; idx++) {
        if (array[idx] == array[idx-1] + 1)
            conseq++;
        else
            conseq = 1;
        if (conseq == 5)
            return true;
    }
    return false;
}

console.log(testArray(should_be_true)); //true
console.log(testArray(should_be_false)); //false

But for bonus fun, here's one variation on a functional approach, returning the position where the sequence starts, or -1 if no sufficiently long sequence exists:

should_be_true.map(function(curr,idx,arr) {
    return (curr == arr[idx-1] +1) ? 1 : 0;
}).join('').search(/1{4}/); 
Sign up to request clarification or add additional context in comments.

Comments

3

A functional approach would be

function fiveInARow(array) {

  // compare if one element is greater than or equal to the previous one
  function compare(elt, i, arr) { return !i || elt >= arr[i-1]; });

  // check if at a given position, every one of the last five comparisons is true
  function check (_, i, greaters) { 
    return i >= 4 && greaters.slice(i-4, i) . every(Boolean);                         
  }

  return array . map(compare) . some(check);
}

The logic here is to first create an array of booleans using map, showing whether each element is greater than or equal to the previous. That yields an array such as [true, true, true, false, true].

The some part asks, for any element, is it the case that that element and every one of the preceding four elements are true? If so, it returns true.

Recursive solution

A recursive solution might be a bit easier to read.

function fiveInARow(array) {

  return function _five(array, prev, n) {
    if (n >= 5)        return true;
    if (!array.length) return false;

    var next = array.shift();
    return _five(array, next, next === prev ? n : next >= prev ? n+1 : 0);
  }(array, -999999, 5);

}

Comments

0
var array = [1,3,5,7,7,8,9,10,11];
var cons=false;
var count=0;
for(i=0;i<array.length;i++){
    if(array[i]+1==array[i+1]){
        count++;
    }
    else{
        count=0;
    }
    if(count==4){
        cons=true;
    }
}
if(cons){
    //do what you want with it
}

DEMO

a more elegant way would be to define this whole thing in a function as below:

function checkCons(array){
    var cons=false;
    var count=0;
    for(i=0;i<array.length;i++){
        if(array[i]+1==array[i+1]){
            count++;
        }
        else{
            count=0;
        }
        if(count==4){
            cons=true;
        }
    }
    return cons;
}

and then using it like this:

var array = [1,3,5,7,7,8,9,10,11];
if(checkCons(array)){
    //do what you want with it
}

DEMO

Comments

0
   function fiveStraight() {
       var array = [1, 3, 5, 7, 7, 8, 9, 10, 12];
       var prev = array[0];
       var numberOfStraight = 1;

       for (var i = 1; i < array.length; i++) {
           numberOfStraight = array[i] === prev + 1 ? numberOfStraight + 1 : 1;
           prev = array[i];
           if (numberOfStraight === 5) return true;
       }

       return false;
   }

JSFIDDLE.

3 Comments

Would it be more efficient to check 5+ ahead of each index before doing consecutive order check?
I don't think so. The worst case = go through the whole array. The best case is if the streak falls on the first number. I start from the beginning and go towards the end. If I find a streak I return true. If not and I got to the end I return false. I don't see how you can improve that approach.
Actually, that's an interesting question. You CAN roughly double the efficiency of this search by only reading every second position (incrementing your index by 2 instead of 1). If the two values differ by 2, go back and check the one in between. You'll avoid some number of unnecessary reads that way...n/2 in the case where no sequence was present.
0

Here is what I found out to be the most straight forwards approach. Both descending and ascending values count as consecutive (if that's not your case, then fiddle with the Math.abs() call).

function consecutiveValuesCount(array) {
    // sort the values if not pre-sorted
    var sortedValues = array.sort();

    // the result variable / how many consecutive numbers did we find?
    // there's always atleast 1 consecutive digit ...
    var count = 1;
    for (var i = 0; i < sortedValues.length - 1; i++) {
        // both descending and ascending orders count as we are using Math.abs()
        if (Math.abs(sortedValues[i] - sortedValues[i+1]) == 1) {
          ++count;
        }
    }
    return count;
}

//input
var array = [1,2,4,5,3];
// output
5

Comments

0

with this code you can find the highest number of consecutives for a given number or find the highest number of consecutives in general

var findMaxConsecutiveOnes = function (arr, number) {
   //check for boundries
   if(!number || !arr.length) return;

  // maximum number of consectuives
  let max = 0;

  // count homy many consecutives before it ends (why it's 1 ? because a lonely number is still counted)
  let counter = 1;

  // you can ignore the next 2 variable if you want to use for loop instead of while
  let length = arr.length;
  let i = 1; // counting from index 1 because we are checking against index-1
  while (i < length) {

    if (arr[i] == arr[i - 1]) {

      // boom, we have a consecutive, count it now
      counter++;
    } else {

      // rest to 1
      counter = 1;
    }

    // always update the max variable to the new max value
    max = Math.max(counter, max);

    //for the sake of iteration
    i++;
  }
  return max== number;
};
console.log(findMaxConsecutiveOnes([5, 5, 5, 1, 1, 1, 1, 1]));

1 Comment

Sorry, it was my first answer :D gonna edit it
-3

cnt will only increase once, when it hits the two 7s.

Put the incrementing line in the truthy condition, and the reset line in the else statement.

// Put into a function for testing.
function foo() {
  var array = [1, 3, 5, 7, 7, 8, 9, 10, 11]
  var current = null;
  var cnt = 0;

  for (var i = 0; i < array.length; i++) {
    // Also need to make sure the next array item is a consecutive increase.
    if (array[i] != current && array[i] === array[i-1] + 1) {
      if (cnt > 4) {
        return true;
      }

      current = array[i];
      cnt++;
    } else {
      cnt = 1;
    }
  }

  if (cnt > 4) {
    return true;
  } else {
    return false;
  }
};

// Call function.
alert(foo());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.