loading...

Daily Challenge #278 - Find all non-consecutive numbers

thepracticaldev profile image dev.to staff ・1 min read

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!

Posted on by:

thepracticaldev profile

dev.to staff

@thepracticaldev

The hardworking team behind dev.to ❤️

Discussion

markdown guide
 

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}))
 

Bravo! You did what I could not 😂

 

You could. You just need to go on step forward

 

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
 

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 },
    ]);
}
 
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

 

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;
}
 

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}]
 

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
 

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'.

 

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
 

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))

 

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 []
 

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

 

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;
}
 

You could do it in one :)

 

SWI Prolog again

nonconsecutive(List, NC) :-
  findall(
    X,
    (
      nextto(A, B, List),
      \+ succ(A, B),
      nth0(Index, List, B),
      X = Index-B
    ),
    NC).
 

Ruby

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