DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

dev.to staff
dev.to staff

Posted on

Daily Challenge #278 - Find all non-consecutive numbers

Your task is to find all the elements of an array that are non consecutive. A number is considered non consecutive if it is not exactly one larger than the previous element in the array. The first element always gets a pass.

You should return the results as an array of objects with two values i: and n: .

Example

For the the array [1,2,3,4,6,7,8,10], the result should be:

nconsecutive([1,2,3,4,6,7,8,10])
[
  {'i': 4, 'n': 6},
  {'i': 7, 'n': 15}
]

Tests

[6,7,8,9,11,12]
[100,101,102,112,113,114,129]

Good luck!


This challenge comes from thecodeite on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Top comments (18)

Collapse
 
mintypt profile image
mintyPT

Here's mine

const nconsecutive = input => input.map((x,i) => [x, input[i+1], i+1]).filter(([b,f,i]) => b+1 != f && f != undefined).map(([_,n,i])=>({n,i}))
Collapse
 
kylejschwartz profile image
Kyle Schwartz

Bravo! You did what I could not πŸ˜‚

Collapse
 
mintypt profile image
mintyPT

You could. You just need to go on step forward

Collapse
 
peter279k profile image
peter279k

Here is the simple solution with Python:

def all_non_consecutive(arr):
    ans = []
    start = arr[0]
    index = 0
    for number in arr:
        if start == number:
            start += 1
            index += 1
            continue

        ans.append({'i': index, 'n': number})
        start = number + 1
        index += 1

    return ans
Collapse
 
idanarye profile image
Idan Arye

Rust:

#[derive(Debug, PartialEq)]
struct IndexAndNumber {
    i: usize,
    n: isize,
}

fn nconsecutive(numbers: &[isize]) -> Vec<IndexAndNumber> {
    let mut it = numbers.iter().enumerate();
    let mut prev = if let Some((_, first_number)) = it.next() {
        *first_number
    } else {
        return Vec::new();
    };
    it.filter_map(|(i, &n)| {
        let is_consecutive = n == prev + 1;
        prev = n;
        if is_consecutive {
            None
        } else {
            Some(IndexAndNumber { i, n })
        }
    }).collect()
}

fn main() {
    assert_eq!(nconsecutive(&[6, 7, 8, 9, 11, 12]), &[
        IndexAndNumber { i: 4, n: 11 }
    ]);
    assert_eq!(nconsecutive(&[100, 101, 102, 112, 113, 114, 129]), &[
        IndexAndNumber { i: 3, n: 112 },
        IndexAndNumber { i: 6, n: 129 },
    ]);
}
Collapse
 
qm3ster profile image
Mihail Malo
use core::iter::Enumerate;
#[derive(Debug, PartialEq)]
struct IndexAndNumber {
    i: usize,
    n: isize,
}
struct NonCons<I: Iterator<Item = isize>> {
    prev: isize,
    iter: Enumerate<I>,
}
impl<I: Iterator<Item = isize>> NonCons<I> {
    fn new<II: IntoIterator<Item = isize, IntoIter = I>>(it: II) -> Option<Self> {
        let mut iter = it.into_iter().enumerate();
        let prev = iter.next()?.1;
        Some(Self { prev, iter })
    }
}
impl<I: Iterator<Item = isize>> Iterator for NonCons<I> {
    type Item = IndexAndNumber;
    fn next(&mut self) -> Option<Self::Item> {
        for (i, n) in &mut self.iter {
            if (std::mem::replace(&mut self.prev, n) + 1) != n {
                return Some(IndexAndNumber { i, n });
            }
        }
        None
    }
}

fn nconsecutive(numbers: &[isize]) -> Vec<IndexAndNumber> {
    NonCons::new(numbers.into_iter().copied()).unwrap().collect()
}

huhuhu iterator

Collapse
 
aminnairi profile image
Amin

TypeScript

interface IndexValue {
    index: number;
    value: number;
}

/**
 * Return all numbers with their index & value that are not following the others.
 *
 * @example
 * getNonConsecutives([1, 2, 3]);
 * getNonConsecutives([1, 2, 4]);
 */
function getNonConsecutives(numbers: Readonly<Array<number>>): Array<IndexValue> {
    const nonConsecutives: Array<IndexValue> = [];
    const count: number = numbers.length;

    for (let index: number = 1; index < count; index++) {
        const current: number = numbers[index];
        const previous: number = numbers[index - 1];
        const expectedCurrent: number = previous + 1;

        if (expectedCurrent === current) {
            continue;
        }

        nonConsecutives.push({index, value: current});
    }

    return nonConsecutives;
}
Collapse
 
cipharius profile image
Valts Liepiņő

Haskell solution:

import Data.Foldable (foldl')

data IndexedNumber = IndexedNumber
  { index :: Int
  , number :: Int
  } deriving Show

nconsecutive :: [Int] -> [IndexedNumber]
nconsecutive xs = reverse $ foldl' compute [] indexedPairs
  where
    indexedPairs = zip3 [1..] xs (tail xs)
    compute result (i, x, x')
      | x' - x == 1 = result
      | otherwise   = (IndexedNumber i x') : result

Test results:

> nconsecutive [6,7,8,9,11,12]
[IndexedNumber {index = 4, number = 11}]

> nconsecutive [100,101,102,112,113,114,129]
[IndexedNumber {index = 3, number = 112},IndexedNumber {index = 6, number = 129}]
Collapse
 
rafi993 profile image
Rafi

Ruby

def nconsecutive(array)
 prev = array[0]
 output = []
 array.drop(1).each_with_index do | i, index |
    if prev + 1 != i
        output.push({ i: i, n: index + 1 })
    end
    prev = i
 end

 return output
end
Collapse
 
bb4l profile image
bb4L

for clarification, from the challenge:

E.g., if we have an array [1,2,3,4,6,7,8,15,16] then 6 and 15 are non-consecutive.
You should return the results as an array of objects with two values i: 'the index of the non-consecutive number' and n: 'the non-consecutive number'.

Collapse
 
rafaacioly profile image
Rafael Acioly • Edited on

Python solution 🐍

from typing import List, Dict


def non_consecutive(numbers: List[int]) -> List[Dict]:
  result: List[Dict] = []
  last_number =  numbers[0]
  for index, current_number in enumerate(numbers[1:], start=1):
    if not current_number - 1 == last_number:
      result.append({'i': index, 'n': number})

    last_number = number

  return result
Collapse
 
bb4l profile image
bb4L

solution in Nim:


type
    ReturnData* = object
        i*, n*: int

proc allNonConsecutive*(data: seq[int]): seq[ReturnData] =
    for i, n in data[ .. (data.len-2)].pairs:
        if n + 1 != data[i+1]:
            result.add(ReturnData(n: data[i+1], i: i+1))

Collapse
 
jingxue profile image
Jing Xue

A python solution:

def nconsecutive(arr):
    return [{'i': i, 'n': arr[i]} for i in range(1, len(arr)) if arr[i - 1] + 1 != arr[i]] if len(arr) > 1 else []
Collapse
 
idanarye profile image
Idan Arye

BTW: the example is wrong. {'i': 7, 'n': 15} should be {'i': 7, 'n': 10} - there is no 15 in the input.

Collapse
 
kylejschwartz profile image
Kyle Schwartz

JavaScript solution in 5 lines

const nconsecutive = arr => {
    const arr2 = [];
    arr.forEach((n, i) => (i > 0 && n - 1 !== arr[i-1]) ? arr2.push({i, n}) : false);
    return arr2;
}
Collapse
 
mintypt profile image
mintyPT • Edited on

You could do it in one :)

Collapse
 
n8chz profile image
Lorraine Lee

SWI Prolog again

nonconsecutive(List, NC) :-
  findall(
    X,
    (
      nextto(A, B, List),
      \+ succ(A, B),
      nth0(Index, List, B),
      X = Index-B
    ),
    NC).
Collapse
 
n8chz profile image
Lorraine Lee

Ruby

def nonconsecutive(a)
  a.each_with_index.drop(1).to_h.invert.select{|k, v| v-a[k-1] != 1}
end

We are hiring! Do you want to be our Senior Platform Engineer? Are you capable of chipping in across sysadmin, ops, and site reliability work, while supporting the open source stack that runs DEV and other communities?

This role might just be for you!

Apply now