The challenge

Your task is to find the first element of an array that is not consecutive.

By not consecutive we mean not exactly 1 larger than the previous element of the array.

E.g. If we have an array [1,2,3,4,6,7,8] then 1 then 2 then 3 then 4 are all consecutive but 6 is not, so that’s the first non-consecutive number.

If the whole array is consecutive then return null.

The array will always have at least 2 elements1 and all elements will be numbers. The numbers will also all be unique and in ascending order. The numbers could be positive or negative and the first non-consecutive could be either too!

Can you write a solution that will return null for both [] and [ x ] though? (This is an empty array and one with a single number and is not tested for, but you can write your own example test. )

The solution in Java code

In our solution, we loop through all elements of the array, except for the last element. Each time checking if the next element’s value is 1 more than the current element.

If it is not, then we return the next element’s value.

If all else fails, and we complete our loop, then we return null.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class FirstNonConsecutive {
    static Integer find(final int[] array) {
        
        for (int i=0; i<array.length-1; i++) {
            if (array[i+1]!=array[i]+1)
              return array[i+1];
        }
      
        return null;
    }
}

We could also come to a similar solution by using the IntStream functionality, as follows:

1
2
3
4
5
6
7
8
import java.util.stream.*;

class FirstNonConsecutive {
    static Integer find(final int[] array) {
      return IntStream.range(1, array.length).filter(i -> array[i-1] != array[i]-1)
                     .mapToObj(x -> new Integer(array[x])).findFirst().orElse(null);
    }
}

Test cases to validate our Java code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public final class FirstNonConsecutiveTest {
    @Test public void basicTests() {
        assertEquals(Integer.valueOf(6), FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 6, 7, 8}));
        assertEquals(null, FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 5, 6, 7, 8}));
        assertEquals(Integer.valueOf(6), FirstNonConsecutive.find(new int[]{4, 6, 7, 8, 9, 11}));
        assertEquals(Integer.valueOf(11), FirstNonConsecutive.find(new int[]{4, 5, 6, 7, 8, 9, 11}));
        assertEquals(null, FirstNonConsecutive.find(new int[]{31, 32}));
        assertEquals(Integer.valueOf(0), FirstNonConsecutive.find(new int[]{-3, -2, 0, 1}));
        assertEquals(Integer.valueOf(-1), FirstNonConsecutive.find(new int[]{-5, -4, -3, -1}));
    }
}

Extended test cases

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import java.util.Arrays;
import java.util.Random;
import java.util.Set;
import java.util.HashSet;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public final class FirstNonConsecutiveTest {
    @Test public void basicTests() {
        assertEquals(Integer.valueOf(6), FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 6, 7, 8}));
        assertEquals(null, FirstNonConsecutive.find(new int[]{1, 2, 3, 4, 5, 6, 7, 8}));
        assertEquals(Integer.valueOf(6), FirstNonConsecutive.find(new int[]{4, 6, 7, 8, 9, 11}));
        assertEquals(Integer.valueOf(11), FirstNonConsecutive.find(new int[]{4, 5, 6, 7, 8, 9, 11}));
        assertEquals(null, FirstNonConsecutive.find(new int[]{31, 32}));
        assertEquals(Integer.valueOf(0), FirstNonConsecutive.find(new int[]{-3, -2, 0, 1}));
        assertEquals(Integer.valueOf(-1), FirstNonConsecutive.find(new int[]{-5, -4, -3, -1}));
    }

    @Test public void randomTests() {
        Random random = new Random();
        for (int i = 0; i < 20; i++) {
            int length = random.nextInt(15) + 1;
            int[] array = new int[length];
            int start = random.nextInt(10000) - (10000/4); //25% should start less than zero
            for (int j=0; j<length; j++) {
              array[j] = start;
              start++;
              if (random.nextInt(100) > 90) start++;
            }
            assertEquals("For input \"" + Arrays.toString(array) + '"', kata(array), FirstNonConsecutive.find(array));
        }
    }

    private static Integer kata(final int[] array) {
        for (int i = 1; i < array.length; i++) {
            if (array[i] != array[i - 1] + 1) {
                return array[i];
            }
        }
        return null;
    }
}