User1899289003
User1899289003

Reputation: 872

Check if array elements are consecutive without order

I have the following code:

int[] arr = { 1, 2, 3, 4 };
int n = arr.Length;
bool result = areConsecutives(arr, n);
if (result == true)
    MessageBox.Show("Yes");
else
    MessageBox.Show("No"); 

static bool areConsecutives(int[] arr, int n)
{
    int first_term = int.MaxValue;

    for (int j = 0; j < n; j++)
    {
        if (arr[j] < first_term)
            first_term = arr[j];
    }

    int ap_sum = (n * (2 * first_term + (n - 1) * 1)) / 2;

    int arr_sum = 0;
    for (int i = 0; i < n; i++)
        arr_sum += arr[i];

    return ap_sum == arr_sum;
} 

This works fine even if I change my array to this:

int[] arr = { 4, 2, 1, 3 }

The problem/question is what can I do to check if the array elements are consecutive, for example if I have the following array:

int[] arr = { 4, 8, 12, 16 }

They are consecutive/multiple by 4 and also the array can be in this way:

int[] arr = { 16, 4, 8, 12 }

Upvotes: 0

Views: 867

Answers (4)

Pavel Anikhouski
Pavel Anikhouski

Reputation: 23228

A possible solution using Array.Sort and simple for loop, without System.Linq

int[] arr = { 16, 4, 8, 12 };
Array.Sort(arr);

bool result = true;
for (int i = 1; i < arr.Length - 1; i++)
    if (arr[i] - arr[i - 1] != arr[i + 1] - arr[i])
    {
        result = false;
        break;
    }

Upvotes: 1

Peter B
Peter B

Reputation: 24147

I would do it like this: determine which values are needed, and then check if arr contains each of those values.

var min = arr.Min(); // This is also the expected "gap" between elements
var max = min * arr.Length;
var isOK = min > 0;
for (var i = min; i <= max && isOK; i += min)
{
    if (!arr.Contains(i))
        isOK = false;
}
Console.WriteLine(isOK ? "Consecutive" : "Not consecutive");

Working demo: https://dotnetfiddle.net/YpSXwF


Or if 0 and negative values are also allowed:

var min = arr.Min();
var gap = arr.Where(x => x > min).Min() - min;
var max = min + gap * (arr.Length - 1);
var isOK = gap > 0;
for (var i = min; i <= max && isOK; i += gap)
{
    if (!arr.Contains(i))
        isOK = false;
}
Console.WriteLine(isOK ? "Consecutive" : "Not consecutive");

Working demo: https://dotnetfiddle.net/k3jGP5

Upvotes: 0

canton7
canton7

Reputation: 42225

Here's one way:

var vals = new[] { 125, 25, 50, 75, 100 };
Array.Sort(vals);
bool arithmetic = vals.Zip(vals.Skip(1), (x, y) => y - x).Distinct().Count() == 1;

We start by sorting the array. Then we take each pair of elements (so take 25 and 50, then 50 and 75, etc) and find the difference between them. Then we take the number of different differences we found, and see if that's 1: if it is, our elements are evenly spaced.


Here's another:

var vals = new[] { 125, 50, 75, 100 };
Array.Sort(vals);
bool areArithmetic = true;
if (vals.Length > 1)
{
    int difference = vals[1] - vals[0]; 
    for (int i = 2; i < vals.Length; i++)
    {
        if (vals[i] != vals[0] + i * difference)
        {
            areArithmetic = false;
            break;
        }
    }
}

Here we sort the list again, and then loop through the sorted list. We find the difference between the first two elements, then check that every subsequent element is an appropriate multiple of that difference.

Upvotes: 5

JSteward
JSteward

Reputation: 7091

If you're not looking for an arithmetic progression and just simply want whether the numbers are consecutively growing then you could do something like this. Just check whether the previous value is ever greater than the current.

var isConsecutive = true;
var numbers = new[] { 1.3, -1, 0, 1.5 };
for (int i = 1; i < numbers.Length; i++)
{
    if (numbers[i - 1] > numbers[i])
    {
        isConsecutive = false;
        break;
    }
}

Upvotes: 3

Related Questions