Home > OS >  program that checks for an tupple: for loop is out of bounds or misses two last elements
program that checks for an tupple: for loop is out of bounds or misses two last elements

Time:11-05

I am making a little program in C# that checks if input is an arithmetic array or a normal array.

The problem is when I make a for loop that checks if the array is arithmetic, I lose the last two elements off the array because i had to reduce numbers.Length with 2, otherwise I would get an error saying its out of bounds. (btw., arithmetic is for example: 2 - 4 - 6 - 8 - 10 - 12, so 2 every time)

int[] numbers = new int[6];

for (int i = 0; i < numbers.Length; i  )
{
    Console.Write("Give a number: ");
    numbers[i] = int.Parse(Console.ReadLine());
}

bool boolArithmetic = false;
bool boolNormal = false;
int counterArithmetic = 0;

for (int i = 0; i < numbers.Length - 2; i  )
{
    if (numbers[i   1] - numbers[i] == numbers[i   2] - numbers[i   1])
    {
        Console.WriteLine("Arithmetic Array");
        Console.WriteLine(i);
        counterArithmetic  ;
        boolArithmetic = true;
    }
    else
    {
        Console.WriteLine("Normal Array");
        Console.WriteLine(i);
        boolNormal = true;
    }
}

if (counterArithmetic == 6 && boolArithmetic)
{
    Console.WriteLine("ARITHMETIC ARRAY");
}
else if (boolNormal)
{
    Console.WriteLine("NORMAL ARRAY");
}

I tried adding 2 to the array but this didn't work at all. I also tried a do while loop but it just confused me even more.

Does someone know how to fix this so that my code work fine?

CodePudding user response:

You don't lose the last two elements. In the body of the loop you check the i 1 and i 2 elements.

Why do you use a counter to count how many pairs have the same difference? Just use a single boolean flag. As soon as you see a difference that doesn't match, set the flag to true and break out of the loop.

bool isArithmetic = true;
for (int i = 0; i < numbers.Length - 2; i  )
{
   if (numbers[i   1] - numbers[i] != numbers[i   2] - numbers[i   1])
   {
       isArithmetic = false;
       break;
   }
}

Now, just check the bool isArithmetic to figure out what to print:

if (isArithmetic)
{
    Console.WriteLine("ARITHMETIC ARRAY");
} 
else
{
    Console.WriteLine("NORMAL ARRAY");
} 

This assumes your array has at least 3 elements. Arrays with less than 3 elements will always be considered "arithmetic arrays" by this logic, since the for loop is never entered.

CodePudding user response:

The condition inside the second for loop should be changed, it should be i < numbers.Length - 3 instead of i < numbers.Length - 2.

If you are checking for arithmetic array, you can actually do the following:

  1. Compute the difference between first two elements, let call it pre-computed difference.
  2. Then starting from third element, calculate the difference of each consecutive terms, lets call it current difference.
  3. Check if the current difference is equal to the pre-computed difference.If not break, and conclude that the array is not arithmetic
  4. Keep on iterating, till you visit the entire array. If you have visited the entire array, then its arithmetic.
int preComputedDiff = numbers[1]-numbers[0];
for(int i = 2;i < numbers.Length -1;i  ){
    int currDiff = numbers[i 1] - numbers[i];
    if(currDiff != preComputedDiff){
                    Console.WriteLine("Normal Array");
     }
}
 Console.WriteLine("ARITHMETIC ARRAY");

Although you have to add the constraints of the array to make the code more suitable.

CodePudding user response:

just modify your code like this:

int[] numbers = new int[6];

        for (int i = 0; i < numbers.Length; i  )
        {
            Console.Write("Give a number: ");
            numbers[i] = int.Parse(Console.ReadLine());
        }
        int counterArithmetic = 0;

        for (int i = 0; i <=numbers.Length-2; i  )
        {
            if ((numbers[i   1] - numbers[i]) == 2)
            {
                counterArithmetic =1;

            }
        }

        if (counterArithmetic == numbers.Length-1)
        {
            Console.WriteLine("ARITHMETIC ARRAY");
        }
        else
        {
            Console.WriteLine("NORMAL ARRAY");
        }

CodePudding user response:

I would extract the arithmetic test into another method. This allows you to separate console input/output from the logic

private static bool IsArithmetic(int[] a)
{
    if (a.Length < 3) {
        return false;
    }
    int delta = a[1] - a[0];
    for (int i = 2; i < a.Length; i  ) {
        if (a[i] - a[i - 1] != delta) {
            return false;
        }
    }
    return true;
}

It is easier to first compute the difference between the two first elements and to reuse it to compare it with the difference between the remaining elements instead of always comparing 3 elements.

Whether a sequence of 0, 1 or two terms is considered to be an arithmetic progression seems not to be clearly defined. See: Minimum number of terms in an arithmetic progression.

Tests:

int[] a1 = { 2, 4, 6, 8, 10, 12 }; // Yes  2
int[] a2 = { 2, 4, 6, 9, 10, 12 }; // No, deviation in the middle
int[] a3 = { 2, 4, 6, 8, 10, 13 }; // No, deviation at the end
int[] a4 = { 1, 4, 6, 8, 10, 12 }; // No, deviation at the beginning
int[] a5 = { 3, 4, 6, 8, 10, 12 }; // No, deviation at the beginning
int[] a6 = { 3, 6, 9, 12, 15 };    // Yes  3
int[] a7 = { 3, 8 };               // No, too short
int[] a8 = { 2, 5, 6, 8, 10, 12 }; // No, deviation at index = 1
int[] a9 = { 2, 4, 5, 8, 10, 12 }; // No, deviation at index = 2

Console.WriteLine($"Is a1 arithmetic: {(IsArithmetic(a1) ? "yes" : "no")}");
Console.WriteLine($"Is a2 arithmetic: {(IsArithmetic(a2) ? "yes" : "no")}");
Console.WriteLine($"Is a3 arithmetic: {(IsArithmetic(a3) ? "yes" : "no")}");
Console.WriteLine($"Is a4 arithmetic: {(IsArithmetic(a4) ? "yes" : "no")}");
Console.WriteLine($"Is a5 arithmetic: {(IsArithmetic(a5) ? "yes" : "no")}");
Console.WriteLine($"Is a6 arithmetic: {(IsArithmetic(a6) ? "yes" : "no")}");
Console.WriteLine($"Is a7 arithmetic: {(IsArithmetic(a7) ? "yes" : "no")}");
Console.WriteLine($"Is a8 arithmetic: {(IsArithmetic(a8) ? "yes" : "no")}");
Console.WriteLine($"Is a9 arithmetic: {(IsArithmetic(a9) ? "yes" : "no")}");

prints:

Is a1 arithmetic: yes
Is a2 arithmetic: no
Is a3 arithmetic: no
Is a4 arithmetic: no
Is a5 arithmetic: no
Is a6 arithmetic: yes
Is a7 arithmetic: no
Is a8 arithmetic: no
Is a9 arithmetic: no

These tests ensure that the logic covers the whole index range.

  •  Tags:  
  • c#
  • Related