Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I determine if *exactly* one boolean is true, without type conversion?

Tags:

logic

boolean

Given an arbitrary list of booleans, what is the most elegant way of determining that exactly one of them is true?

The most obvious hack is type conversion: converting them to 0 for false and 1 for true and then summing them, and returning sum == 1.

I'd like to know if there is a way to do this without converting them to ints, actually using boolean logic.

(This seems like it should be trivial, idk, long week)

Edit: In case it wasn't obvious, this is more of a code-golf / theoretical question. I'm not fussed about using type conversion / int addition in PROD code, I'm just interested if there is way of doing it without that.

Edit2: Sorry folks it's a long week and I'm not explaining myself well. Let me try this:

In boolean logic, ANDing a collection of booleans is true if all of the booleans are true, ORing the collection is true if least one of them is true. Is there a logical construct that will be true if exactly one boolean is true? XOR is this for a collection of two booleans for example, but any more than that and it falls over.

like image 697
SCdF Avatar asked Feb 15 '13 04:02

SCdF


People also ask

How do you know if a boolean value is true?

To check if a value is of boolean type, check if the value is equal to false or equal to true , e.g. if (variable === true || variable === false) . Boolean values can only be true and false , so if either condition is met, the value has a type of boolean. Copied!

What makes a boolean true?

Boolean. TRUE is a reference to an object of the class Boolean, while true is just a value of the primitive boolean type. Classes like Boolean are often called "wrapper classes", and are used when you need an object instead of a primitive type (for example, if you're storing it in a data structure).

What is a boolean * Your answer?

Answer: Boolean is a primitive data type that takes either “true” or “false” values. So anything that returns the value “true' or “false” can be considered as a boolean example. Checking some conditions such as “a==b” or “a<b” or “a>b” can be considered as boolean examples.

Can Booleans only be true or false?

Boolean values are another type of data type in programming languages, and they can only ever hold true or false.


2 Answers

You can actually accomplish this using only boolean logic, although there's perhaps no practical value of that in your example. The boolean version is much more involved than simply counting the number of true values.

Anyway, for the sake of satisfying intellectual curiosity, here goes. First, the idea of using a series of XORs is good, but it only gets us half way. For any two variables x and y,

xy

is true whenever exactly one of them is true. However, this does not continue to be true if you add a third variable z,

xyz

The first part, xy, is still true if exactly one of x and y is true. If either x or y is true, then z needs to be false for the whole expression to be true, which is what we want. But consider what happens if both x and y are true. Then xy is false, yet the whole expression can become true if z is true as well. So either one variable or all three must be true. In general, if you have a statement that is a chain of XORs, it will be true if an uneven number of variables are true.

Since one is an uneven number, this might prove useful. Of course, checking for an uneven number of truths is not enough. We additionally need to ensure that no more than one variable is true. This can be done in a pairwise fashion by taking all pairs of two variables and checking that they are not both true. Taken together these two conditions ensure that exactly one if the variables are true.

Below is a small Python script to illustrate the approach.

from itertools import product  print("x|y|z|only_one_is_true") print("======================") for x, y, z in product([True, False], repeat=3):     uneven_number_is_true = x ^ y ^ z     max_one_is_true = (not (x and y)) and (not (x and z)) and (not (y and z))     only_one_is_true = uneven_number_is_true and max_one_is_true     print(int(x), int(y), int(z), only_one_is_true) 

And here's the output.

 x|y|z|only_one_is_true ====================== 1 1 1 False 1 1 0 False 1 0 1 False 1 0 0 True 0 1 1 False 0 1 0 True 0 0 1 True 0 0 0 False 
like image 99
Anders Johannsen Avatar answered Sep 25 '22 23:09

Anders Johannsen


After your clarification, here it is with no integers.

 bool IsExactlyOneBooleanTrue( bool *boolAry, int size )     {       bool areAnyTrue = false;       bool areTwoTrue = false;       for(int i = 0; (!areTwoTrue) && (i < size); i++) {         areTwoTrue = (areAnyTrue && boolAry[i]);         areAnyTrue |= boolAry[i];       }       return ((areAnyTrue) && (!areTwoTrue));     } 
like image 35
c.fogelklou Avatar answered Sep 21 '22 23:09

c.fogelklou