Logic to test that 3 of 4 are True

I want to return True if and only if 3 out of 4 boolean values are true.

The closest I've gotten is (x ^ y) ^ (a ^ b):

What should I do?


I suggest writing the code in a manner that indicates what you mean. If you want 3 values to be true, it seems natural to me that the value 3 appears somewhere.

For instance, in C++:

if ((int)a + (int)b + (int)c + (int)d == 3)
    ...

This is well defined in C++: the standard (§4.7/4) indicates that converting bool to int gives the expected values 0 or 1.

In Java and C#, you can use the following construct:

if ((a?1:0) + (b?1:0) + (c?1:0) + (d?1:0) == 3)
    ...

#1: Using a branching ?: 3 or 4 operations

A ^ B ? C & D : ( C ^ D ) & A

#2 Non-Branching, 7 operations

(A ^ B ^ C ^ D) & ((A & B) | (C & D))

Back when I use to profile everything, I found non-branching solutions were quite a bit quicker operation-for-operation as the CPU could predict the code path better, and execute more operations in tandem. There is about 50% less work in the branching statement here though.


If this had been Python, I would have written

if [a, b, c, d].count(True) == 3:

Or

if [a, b, c, d].count(False) == 1:

Or

if [a, b, c, d].count(False) == True:
# In Python True == 1 and False == 0

Or

print [a, b, c, d].count(0) == 1

Or

print [a, b, c, d].count(1) == 3

Or

if a + b + c + d == 3:

Or

if sum([a, b, c, d]) == 3:

All these work, since Booleans are subclasses of integers in Python.

if len(filter(bool, [a, b, c, d])) == 3:

Or, inspired by this neat trick,

data = iter([a, b, c, d])
if not all(data) and all(data):