HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Array is Twinoid Or Not

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
arraynottwinoid

Problem

twinoid is defined to be an array that has exactly two even values that are adjacent to one another. For example {3, 3, 2, 6, 7} is a twinoid array because it has exactly two even values (2 and 6) and they are adjacent to one another. The following arrays are not twinoid arrays.

  • {3, 3, 2, 6, 6, 7} because it has three even values.



  • {3, 3, 2, 7, 6, 7} because the even values are not adjacent to one another.



  • {3, 8, 5, 7, 3} because it has only one even value.



I wrote Twinoid to check that given array is twinoid or not.

public class Twinoid {

public static void main(String args[]) {
    System.out.println("The result is: " + isTwinoid(new int[]{3, 3, 2, 6, 7}));
}

public static boolean isTwinoid(int[] a) {
    boolean status = false;
    int i;
    int count = 0;
    for (i = 0; i < a.length; i++) {
        if (a[i] % 2 == 0) {
            count++;
        }
    }
    if (count == 2) {
        int j;
        for (j = 0; j < a.length; j++) {
            if (a[j] % 2 == 0) {
                System.out.println(a[j]);
                break;
            }
        }
        int nextValue = a[j + 1];
        System.out.println(nextValue);
        if (nextValue % 2 == 0) {
            status = true;
        }
    } else {
        status = false;
    }
    return status;
}
}

Solution

You don't need two passes.

boolean status = false;
    int i;
    int count = 0;
    for (i = 0; i < a.length; i++) {
        if (a[i] % 2 == 0) {
            count++;
        }
    }
    if (count == 2) {
        int j;
        for (j = 0; j < a.length; j++) {
            if (a[j] % 2 == 0) {
                System.out.println(a[j]);
                break;
            }
        }
        int nextValue = a[j + 1];
        System.out.println(nextValue);
        if (nextValue % 2 == 0) {
            status = true;
        }
    } else {
        status = false;
    }
    return status;


You can replace this with just

int i;
    for (i = 0; i < a.length - 1; i++) {
        if (a[i] % 2 == 0) {
            i++;
            if (a[i] % 2 == 0) {
                i++;
                break;
            } else {
                return false;
            }
        }
    }

    if (i == a.length && a[i-1] % 2 != 0) {
        return false;
    }

    for (; i < a.length; i++) {
        if (a[i] % 2 == 0) {
            return false;
        }
    }

    return true;


or even shorter

for (int i = 0; i < a.length - 1; i++) {
        if (a[i] % 2 == 0) {
            i++;
            if (a[i] % 2 == 0) {
                i++;
                for (; i < a.length; i++) {
                    if (a[i] % 2 == 0) {
                        return false;
                    }
                }

                return true;
            } else {
                return false;
            }
        }
    }

    return false;


Either of these only requires a single scan.

If they find no even numbers in the first a.length - 1 elements, they fall through and return false.

If they find an even number but the next number is odd, they return false.

If they find two even numbers and then find a third, they return false.

If they find two even numbers and every remaining number is odd, they return true.

This saves both status and count as variables.

But the shortest version that I could write was

int evensCount = 0;
    for (int number : numbers) {
        if (number % 2 == 0) {
            evensCount++;
        } else if (evensCount > 0 && evensCount != 2) {
            return false;
        }
    }

    return evensCount == 2;


Note that I renamed a to numbers in this case. I prefer that kind of name for collections and arrays, and since I only use it once, there was less advantage to terseness.

This version only checks if numbers are even in one place. All the other versions had to do this in multiple places. I believe that makes this code DRYer as well as shorter.

This iterates through the array, counting the even numbers. For each odd number, it checks if it has seen any even numbers. If it has, it checks if it has seen exactly two. If not, it can return false. If it has seen exactly two consecutive even numbers, it keeps going. If it goes all the way through and finds exactly two even numbers, it can return true. Otherwise, it returns false.

So if it sees one even number followed by an odd number, it will abort and return false. The evensCount will be equal to 1.

If it sees three or more consecutive even numbers, it will return false once it sees the next odd number. Or when it is done iterating if the even numbers last until the end.

If it sees two consecutive even numbers and then an odd number, it will search for more even numbers. If it finds one, it will eventually return false. If it doesn't, it will return true after scanning the entire array.

You could sometimes speed it up by adding another if that checks if evensCount is greater than two. However, that will also slow it down in some situations. And of course it is more code. If time is critical, it might help. Or not. It really depends on the inputs. I omitted it because it is only sometimes better at all and I'm not sure we need to optimize to that level.

My test cases:

System.out.println("The result is: " + isTwinoid(new int[]{3, 3, 2, 6, 5, 6, 7}));
    System.out.println("The result is: " + isTwinoid(new int[]{3, 3, 2, 6, 6, 7}));
    System.out.println("The result is: " + isTwinoid(new int[]{3, 3, 2, 7, 6, 7}));
    System.out.println("The result is: " + isTwinoid(new int[]{3, 8, 5, 7, 3}));
    System.out.println("The result is: " + isTwinoid(new int[]{3, 3, 2, 6, 7}));
    System.out.println("The result is: " + isTwinoid(new int[]{3, 3, 2, 6}));


Results:


The result is: false

The result is: false

The result is: false

The result is: false

The result is: true

The result is: true

Code Snippets

boolean status = false;
    int i;
    int count = 0;
    for (i = 0; i < a.length; i++) {
        if (a[i] % 2 == 0) {
            count++;
        }
    }
    if (count == 2) {
        int j;
        for (j = 0; j < a.length; j++) {
            if (a[j] % 2 == 0) {
                System.out.println(a[j]);
                break;
            }
        }
        int nextValue = a[j + 1];
        System.out.println(nextValue);
        if (nextValue % 2 == 0) {
            status = true;
        }
    } else {
        status = false;
    }
    return status;
int i;
    for (i = 0; i < a.length - 1; i++) {
        if (a[i] % 2 == 0) {
            i++;
            if (a[i] % 2 == 0) {
                i++;
                break;
            } else {
                return false;
            }
        }
    }

    if (i == a.length && a[i-1] % 2 != 0) {
        return false;
    }

    for (; i < a.length; i++) {
        if (a[i] % 2 == 0) {
            return false;
        }
    }

    return true;
for (int i = 0; i < a.length - 1; i++) {
        if (a[i] % 2 == 0) {
            i++;
            if (a[i] % 2 == 0) {
                i++;
                for (; i < a.length; i++) {
                    if (a[i] % 2 == 0) {
                        return false;
                    }
                }

                return true;
            } else {
                return false;
            }
        }
    }

    return false;
int evensCount = 0;
    for (int number : numbers) {
        if (number % 2 == 0) {
            evensCount++;
        } else if (evensCount > 0 && evensCount != 2) {
            return false;
        }
    }

    return evensCount == 2;
System.out.println("The result is: " + isTwinoid(new int[]{3, 3, 2, 6, 5, 6, 7}));
    System.out.println("The result is: " + isTwinoid(new int[]{3, 3, 2, 6, 6, 7}));
    System.out.println("The result is: " + isTwinoid(new int[]{3, 3, 2, 7, 6, 7}));
    System.out.println("The result is: " + isTwinoid(new int[]{3, 8, 5, 7, 3}));
    System.out.println("The result is: " + isTwinoid(new int[]{3, 3, 2, 6, 7}));
    System.out.println("The result is: " + isTwinoid(new int[]{3, 3, 2, 6}));

Context

StackExchange Code Review Q#117450, answer score: 5

Revisions (0)

No revisions yet.