Check if at least two out of three booleans are true Check if at least two out of three booleans are true java java

Check if at least two out of three booleans are true


Rather than writing:

if (someExpression) {    return true;} else {    return false;}

Write:

return someExpression;

As for the expression itself, something like this:

boolean atLeastTwo(boolean a, boolean b, boolean c) {    return a ? (b || c) : (b && c);}

or this (whichever you find easier to grasp):

boolean atLeastTwo(boolean a, boolean b, boolean c) {    return a && (b || c) || (b && c);}

It tests a and b exactly once, and c at most once.

References


Just for the sake of using XOR to answer a relatively straight-forward problem...

return a ^ b ? c : a


Why not implement it literally? :)

(a?1:0)+(b?1:0)+(c?1:0) >= 2

In C you could just write a+b+c >= 2 (or !!a+!!b+!!c >= 2 to be very safe).

In response to TofuBeer's comparison of java bytecode, here is a simple performance test:

class Main{    static boolean majorityDEAD(boolean a,boolean b,boolean c)    {        return a;    }    static boolean majority1(boolean a,boolean b,boolean c)    {        return a&&b || b&&c || a&&c;    }    static boolean majority2(boolean a,boolean b,boolean c)    {        return a ? b||c : b&&c;    }    static boolean majority3(boolean a,boolean b,boolean c)    {        return a&b | b&c | c&a;    }    static boolean majority4(boolean a,boolean b,boolean c)    {        return (a?1:0)+(b?1:0)+(c?1:0) >= 2;    }    static int loop1(boolean[] data, int i, int sz1, int sz2)    {        int sum = 0;        for(int j=i;j<i+sz1;j++)        {            for(int k=j;k<j+sz2;k++)            {                sum += majority1(data[i], data[j], data[k])?1:0;                 sum += majority1(data[i], data[k], data[j])?1:0;                 sum += majority1(data[j], data[k], data[i])?1:0;                 sum += majority1(data[j], data[i], data[k])?1:0;                 sum += majority1(data[k], data[i], data[j])?1:0;                 sum += majority1(data[k], data[j], data[i])?1:0;             }        }        return sum;    }    static int loop2(boolean[] data, int i, int sz1, int sz2)    {        int sum = 0;        for(int j=i;j<i+sz1;j++)        {            for(int k=j;k<j+sz2;k++)            {                sum += majority2(data[i], data[j], data[k])?1:0;                 sum += majority2(data[i], data[k], data[j])?1:0;                 sum += majority2(data[j], data[k], data[i])?1:0;                 sum += majority2(data[j], data[i], data[k])?1:0;                 sum += majority2(data[k], data[i], data[j])?1:0;                 sum += majority2(data[k], data[j], data[i])?1:0;             }        }        return sum;    }    static int loop3(boolean[] data, int i, int sz1, int sz2)    {        int sum = 0;        for(int j=i;j<i+sz1;j++)        {            for(int k=j;k<j+sz2;k++)            {                sum += majority3(data[i], data[j], data[k])?1:0;                 sum += majority3(data[i], data[k], data[j])?1:0;                 sum += majority3(data[j], data[k], data[i])?1:0;                 sum += majority3(data[j], data[i], data[k])?1:0;                 sum += majority3(data[k], data[i], data[j])?1:0;                 sum += majority3(data[k], data[j], data[i])?1:0;             }        }        return sum;    }    static int loop4(boolean[] data, int i, int sz1, int sz2)    {        int sum = 0;        for(int j=i;j<i+sz1;j++)        {            for(int k=j;k<j+sz2;k++)            {                sum += majority4(data[i], data[j], data[k])?1:0;                 sum += majority4(data[i], data[k], data[j])?1:0;                 sum += majority4(data[j], data[k], data[i])?1:0;                 sum += majority4(data[j], data[i], data[k])?1:0;                 sum += majority4(data[k], data[i], data[j])?1:0;                 sum += majority4(data[k], data[j], data[i])?1:0;             }        }        return sum;    }    static int loopDEAD(boolean[] data, int i, int sz1, int sz2)    {        int sum = 0;        for(int j=i;j<i+sz1;j++)        {            for(int k=j;k<j+sz2;k++)            {                sum += majorityDEAD(data[i], data[j], data[k])?1:0;                 sum += majorityDEAD(data[i], data[k], data[j])?1:0;                 sum += majorityDEAD(data[j], data[k], data[i])?1:0;                 sum += majorityDEAD(data[j], data[i], data[k])?1:0;                 sum += majorityDEAD(data[k], data[i], data[j])?1:0;                 sum += majorityDEAD(data[k], data[j], data[i])?1:0;             }        }        return sum;    }    static void work()    {        boolean [] data = new boolean [10000];        java.util.Random r = new java.util.Random(0);        for(int i=0;i<data.length;i++)            data[i] = r.nextInt(2) > 0;        long t0,t1,t2,t3,t4,tDEAD;        int sz1 = 100;        int sz2 = 100;        int sum = 0;        t0 = System.currentTimeMillis();        for(int i=0;i<data.length-sz1-sz2;i++)            sum += loop1(data, i, sz1, sz2);        t1 = System.currentTimeMillis();        for(int i=0;i<data.length-sz1-sz2;i++)            sum += loop2(data, i, sz1, sz2);        t2 = System.currentTimeMillis();        for(int i=0;i<data.length-sz1-sz2;i++)            sum += loop3(data, i, sz1, sz2);        t3 = System.currentTimeMillis();        for(int i=0;i<data.length-sz1-sz2;i++)            sum += loop4(data, i, sz1, sz2);        t4 = System.currentTimeMillis();        for(int i=0;i<data.length-sz1-sz2;i++)            sum += loopDEAD(data, i, sz1, sz2);        tDEAD = System.currentTimeMillis();        System.out.println("a&&b || b&&c || a&&c : " + (t1-t0) + " ms");        System.out.println("   a ? b||c : b&&c   : " + (t2-t1) + " ms");        System.out.println("   a&b | b&c | c&a   : " + (t3-t2) + " ms");        System.out.println("   a + b + c >= 2    : " + (t4-t3) + " ms");        System.out.println("       DEAD          : " + (tDEAD-t4) + " ms");        System.out.println("sum: "+sum);    }    public static void main(String[] args) throws InterruptedException    {        while(true)        {            work();            Thread.sleep(1000);        }    }}

This prints the following on my machine (running Ubuntu on Intel Core 2 + sun java 1.6.0_15-b03 with HotSpot Server VM (14.1-b02, mixed mode)):

First and second iterations:

a&&b || b&&c || a&&c : 1740 ms   a ? b||c : b&&c   : 1690 ms   a&b | b&c | c&a   : 835 ms   a + b + c >= 2    : 348 ms       DEAD          : 169 mssum: 1472612418

Later iterations:

a&&b || b&&c || a&&c : 1638 ms   a ? b||c : b&&c   : 1612 ms   a&b | b&c | c&a   : 779 ms   a + b + c >= 2    : 905 ms       DEAD          : 221 ms

I wonder, what could java VM do that degrades performance over time for (a + b + c >= 2) case.

And here is what happens if I run java with a -client VM switch:

a&&b || b&&c || a&&c : 4034 ms   a ? b||c : b&&c   : 2215 ms   a&b | b&c | c&a   : 1347 ms   a + b + c >= 2    : 6589 ms       DEAD          : 1016 ms

Mystery...

And if I run it in GNU Java Interpreter, it gets almost 100 times slower, but the a&&b || b&&c || a&&c version wins then.

Results from Tofubeer with the latest code running OS X:

a&&b || b&&c || a&&c : 1358 ms   a ? b||c : b&&c   : 1187 ms   a&b | b&c | c&a   : 410 ms   a + b + c >= 2    : 602 ms       DEAD          : 161 ms

Results from Paul Wagland with a Mac Java 1.6.0_26-b03-383-11A511

a&&b || b&&c || a&&c : 394 ms    a ? b||c : b&&c   : 435 ms   a&b | b&c | c&a   : 420 ms   a + b + c >= 2    : 640 ms   a ^ b ? c : a     : 571 ms   a != b ? c : a    : 487 ms       DEAD          : 170 ms