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.
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,
x ⊻ y
is true whenever exactly one of them is true. However, this does not continue to be true if you add a third variable z,
x ⊻ y ⊻ z
The first part, x ⊻ y, 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 x ⊻ y 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
Sure, you could do something like this (pseudocode, since you didn't mention language):
found = false;
alreadyFound = false;
for (boolean in booleans):
if (boolean):
found = true;
if (alreadyFound):
found = false;
break;
else:
alreadyFound = true;
return found;
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));
}
No-one mentioned that this "operation" we're looking for is shortcut-able similarly to boolean AND and OR in most languages. Here's an implementation in Java:
public static boolean exactlyOneOf(boolean... inputs) {
boolean foundAtLeastOne = false;
for (boolean bool : inputs) {
if (bool) {
if (foundAtLeastOne) {
// found a second one that's also true, shortcut like && and ||
return false;
}
foundAtLeastOne = true;
}
}
// we're happy if we found one, but if none found that's less than one
return foundAtLeastOne;
}
With plain boolean logic, it may not be possible to achieve what you want. Because what you are asking for is a truth evaluation not just based on the truth values but also on additional information(count in this case). But boolean evaluation is binary logic, it cannot depend on anything else but on the operands themselves. And there is no way to reverse engineer to find the operands given a truth value because there can be four possible combinations of operands but only two results. Given a false, can you tell if it is because of F ^ F or T ^ T in your case, so that the next evaluation can be determined based on that?.
booleanList.Where(y => y).Count() == 1;
Due to the large number of reads by now, here comes a quick clean up and additional information.
Option 1:
Ask if only the first variable is true, or only the second one, ..., or only the n-th variable.
x1 & !x2 & ... & !xn |
!x1 & x2 & ... & !xn |
...
!x1 & !x2 & ... & xn
This approach scales in O(n^2), the evaluation stops after the first positive match is found. Hence, preferred if it is likely that there is a positive match.
Option 2:
Ask if there is at least one variable true in total. Additionally check every pair to contain at most one true variable (Anders Johannsen's answer)
(x1 | x2 | ... | xn) &
(!x1 | !x2) &
...
(!x1 | !xn) &
(!x2 | !x3) &
...
(!x2 | !xn) &
...
This option also scales in O(n^2) due to the number of possible pairs. Lazy evaluation stops the formula after the first counter example. Hence, it is preferred if its likely there is a negative match.
(Option 3):
This option involves a subtraction and is thus no valid answer for the restricted setting. Nevertheless, it argues how looping the values might not be the most beneficial solution in an unrestricted stetting.
Treat x1 ... xn as a binary number x. Subtract one, then AND the results. The output is zero <=> x1 ... xn contains at most one true value. (the old "check power of two" algorithm)
x 00010000
x-1 00001111
AND 00000000
If the bits are already stored in such a bitboard, this might be beneficial over looping. Though, keep in mind this kills the readability and is limited by the available board length.
A last note to raise awareness: by now there exists a stack exchange called computer science which is exactly intended for this type of algorithmic questions
It can be done quite nicely with recursion, e.g. in Haskell
-- there isn't exactly one true element in the empty list
oneTrue [] = False
-- if the list starts with False, discard it
oneTrue (False : xs) = oneTrue xs
-- if the list starts with True, all other elements must be False
oneTrue (True : xs) = not (or xs)
// Javascript
Use .filter() on array and check the length of the new array.
// Example using array
isExactly1BooleanTrue(boolean:boolean[]) {
return booleans.filter(value => value === true).length === 1;
}
// Example using ...booleans
isExactly1BooleanTrue(...booleans) {
return booleans.filter(value => value === true).length === 1;
}
One way to do it is to perform pairwise AND and then check if any of the pairwise comparisons returned true with chained OR. In python I would implement it using
from itertools import combinations
def one_true(bools):
pairwise_comp = [comb[0] and comb[1] for comb in combinations(bools, 2)]
return not any(pairwise_comp)
This approach easily generalizes to lists of arbitrary length, although for very long lists, the number of possible pairs grows very quickly.
Python:
boolean_list.count(True) == 1
OK, another try. Call the different booleans b[i], and call a slice of them (a range of the array) b[i .. j]. Define functions none(b[i .. j]) and just_one(b[i .. j]) (can substitute the recursive definitions to get explicit formulas if required). We have, using C notation for logical operations (&& is and, || is or, ^ for xor (not really in C), ! is not):
none(b[i .. i + 1]) ~~> !b[i] && !b[i + 1]
just_one(b[i .. i + 1]) ~~> b[i] ^ b[i + 1]
And then recursively:
none(b[i .. j + 1]) ~~> none(b[i .. j]) && !b[j + 1]
just_one(b[i .. j + 1] ~~> (just_one(b[i .. j]) && !b[j + 1]) ^ (none(b[i .. j]) && b[j + 1])
And you are interested in just_one(b[1 .. n]).
The expressions will turn out horrible.
Have fun!
That python script does the job nicely. Here's the one-liner it uses:
((x ∨ (y ∨ z)) ∧ (¬(x ∧ y) ∧ (¬(z ∧ x) ∧ ¬(y ∧ z))))
Retracted for Privacy and Anders Johannsen provided already correct and simple answers. But both solutions do not scale very well (O(n^2)). If performance is important you can stick to the following solution, which performs in O(n):
def exact_one_of(array_of_bool):
exact_one = more_than_one = False
for array_elem in array_of_bool:
more_than_one = (exact_one and array_elem) or more_than_one
exact_one = (exact_one ^ array_elem) and (not more_than_one)
return exact_one
(I used python and a for loop for simplicity. But of course this loop could be unrolled to a sequence of NOT, AND, OR and XOR operations)
It works by tracking two states per boolean variable/list entry:
is there exactly one "True" from the beginning of the list until this entry?
are there more than one "True" from the beginning of the list until this entry?
The states of a list entry can be simply derived from the previous states and corresponding list entry/boolean variable.
Python:
let see using example...
steps:
below function exactly_one_topping takes three parameter
stores their values in the list as True, False
Check whether there exists only one true value by checking the count to be exact 1.
def exactly_one_topping(ketchup, mustard, onion):
args = [ketchup,mustard,onion]
if args.count(True) == 1: # check if Exactly one value is True
return True
else:
return False
How do you want to count how many are true without, you know, counting? Sure, you could do something messy like (C syntax, my Python is horrible):
for(i = 0; i < last && !booleans[i]; i++)
;
if(i == last)
return 0; /* No true one found */
/* We have a true one, check there isn't another */
for(i++; i < last && !booleans[i]; i++)
;
if(i == last)
return 1; /* No more true ones */
else
return 0; /* Found another true */
I'm sure you'll agree that the win (if any) is slight, and the readability is bad.
It is not possible without looping. Check BitSet cardinality() in java implementation.
http://fuseyism.com/classpath/doc/java/util/BitSet-source.html
We can do it this way:-
if (A=true or B=true)and(not(A=true and B=true)) then
<enter statements>
end if
The Perl defined function (and many others) returns "a Boolean value".
Given Perl doesn't actually have a Boolean type (and uses values like 1 for true, and 0 or undef for false) does the Perl language specify exactly what is returned for a Boolean values? For example, would defined(undef) return 0 or undef, and is it subject to change?
In almost all cases (i.e. unless there's a reason to do otherwise), Perl returns one of two statically allocated scalars: &PL_sv_yes (for true) and &PL_sv_no (for false). This is them in detail:
>perl -MDevel::Peek -e"Dump 1==1"
SV = PVNV(0x749be4) at 0x3180b8
REFCNT = 2147483644
FLAGS = (PADTMP,IOK,NOK,POK,READONLY,pIOK,pNOK,pPOK)
IV = 1
NV = 1
PV = 0x742dfc "1"\0
CUR = 1
LEN = 12
>perl -MDevel::Peek -e"Dump 1==0"
SV = PVNV(0x7e9bcc) at 0x4980a8
REFCNT = 2147483647
FLAGS = (PADTMP,IOK,NOK,POK,READONLY,pIOK,pNOK,pPOK)
IV = 0
NV = 0
PV = 0x7e3f0c ""\0
CUR = 0
LEN = 12
yes is a triple var (IOK, NOK and POK). It contains a signed integer (IV) equal to 1, a floating point number (NV) equal to 1, and a string (PV) equal to 1.
no is also a triple var (IOK, NOK and POK). It contains a signed integer (IV) equal to 0, a floating point number (NV) equal to 0, and an empty string (PV). This means it stringifies to the empty string, and it numifies to 0. It is neither equivalent to an empty string
>perl -wE"say 0+(1==0);"
0
>perl -wE"say 0+'';"
Argument "" isn't numeric in addition (+) at -e line 1.
0
nor to 0
>perl -wE"say ''.(1==0);"
>perl -wE"say ''.0;"
0
There's no guarantee that this will always remain the case. And there's no reason to rely on this. If you need specific values, you can use something like
my $formatted = $result ? '1' : '0';
They return a special false value that is "" in string context but 0 in numeric context (without a non-numeric warning). The true value isn't so special, since it's 1 in either context. defined() does not return undef.
(You can create similar values yourself with e.g. Scalar::Util::dualvar(0,"").)
Since that's the official man page I'd say that its exact return value is not specified. If the Perl documentation talks about a Boolean value then then it almost always talks about evaluating said value in a Boolean context: if (defined ...) or print while <> etc. In such contexts several values evaluate to a false: 0, undef, "" (empty strings), even strings equalling "0".
All other values evaluate to true in a Boolean context, including the infamous example "0 but true".
As the documentation is that vague I would not ever rely on defined() returning any specific value for the undefined case. However, you'll always be OK if you simply use defined() in a Boolean context without comparing it to a specific value.
OK: print "yes\n" if defined($var)
Not portable/future proof: print "yes\n" if defined($var) eq '' or something similar
It probably won't ever change, but perl does not specify the exact boolean value that defined(...) returns.
When using Boolean values good code should not depend on the actual value used for true and false.
Example:
# not so great code:
my $bool = 0; #
...
if (some condition) {
$bool = 1;
}
if ($bool == 1) { ... }
# better code:
my $bool; # default value is undef which is false
$bool = some condition;
if ($bool) { ... }
99.9% of the time there is no reason to care about the value used for the boolean.
That said, there are some cases when it is better to use an explicit 0 or 1 instead of the boolean-ness of a value. Example:
sub foo {
my $object = shift;
...
my $bool = $object;
...
return $bool;
}
the intent being that foo() is called with either a reference or undef and should return false if $object is not defined. The problem is that if $object is defined foo() will return the object itself and thus create another reference to the object, and this may interfere with its garbage collection. So here it would be better to use an explicit boolean value here, i.e.:
my $bool = $object ? 1 : 0;
So be careful about using a reference itself to represent its truthiness (i.e. its defined-ness) because of the potential for creating unwanted references to the reference.
Suppose I have a text variable $$string.
How can I write a boolean to check whether $$string contains the text $$substring?
e.g. if $$string is "foobar" and $$substring is "oo", then the result should be True, and if the $$string is "foo" and $$substring is "bar" the result should be False.
For a problem like this I'm partial to the PatternCount function:
PatternCount($$string ; $$substring)
You should then get back false = 0 or true >= 1. You can force true to 1 as follows:
PatternCount($$string ; $$substring) > 0
Function Definition here: http://fmhelp.filemaker.com/fmphelp_10/en/html/func_ref3.33.73.html
Use the Position function:
Position($$string;$$substring;1;1)>0
Note: Position($$string;$$substring;a;b) checks whether $$substring is contained at least b-times in $$string from starting position a, and returns where the b th occurrence is located in $$string, or -1 if there is no b th occurrence. Counting starts from 1.
I am developing an application where i need to define several constants that will be used in more than one class.I have defined all my constants in one .h file(say "constants.h") and imported that file in myAppName_Prefix.pch file located in "Other sources" folder of the project.The classes using these constants are being compiled with out any error but other classes, where i declared some UISwipeGestureRecognizers, are throwing error as"Expected identifier before numeric constant"
this is the snippet of code from one of the classes that is showing error:
if (gesture.direction==UISwipeGestureRecognizerDirectionLeft)
i defined my constants as:
#define heading 1
#define direction 2
#define statement 3
#define refLink 4
#define correctResponse 5
#define incorrect1Response 6
if i define them in each class individually then everything as working fine.
Can any one please suggest me a way how to solve this issue.
After preprocessing your code
if (gesture.direction==UISwipeGestureRecognizerDirectionLeft)
looks like this
if (gesture. 2==UISwipeGestureRecognizerDirectionLeft)
and this is obviously not valid code.
The solution is to put an unique namespace string in front of your #defines.
#define hariDirection 2
or
#define kDirection 2
Or imho the best solution: don't use #define
typedef enum {
heading = 1,
direction,
statement,
refLink,
correctResponse,
incorrect1Response,
} MyDirection;
This will do the same thing, but it won't clash with other method and variable names.
I was getting the same error message from gcc.
error: expected ')' before numeric constant
#define UNIQUE_NAME 0
After checking that my variable names were unique, I realised that I had a typo at the point in the code where the constant was being used.
#define UNIQUE_NAME 0
//...
if (test_variable UNIQUE_NAME) { //missing ==
//...
}
simple mistake, but tricky to find because gcc was pointing me towards the #define statement
Make your constants names to be unique:
#define kHeading 1
#define kDirection 2
#define kStatement 3
#define kRefLink 4
#define kCorrectResponse 5
#define kIncorrect1Response 6
There are different kind of macros in the C language, nested macro is one of them.
Considering a program with the following macro
#define HYPE(x,y) (SQUR(x)+SQUR(y))
#define SQUR(x) (x*x)
Using this we can successfully compile to get the result.
As we all know the C preprocessor replaces all the occurrence of the identifiers with the replacement-string. Considering the above example I would like to know how many times the C preprocessor traverses the program to replace the macro with the replacement values. I assume it cannot be done in one go.
the replacement takes place, when "HYPE" is actually used. it is not expanded when the #define statement occurs.
eg:
1 #define FOO 1
2
3 void foo() {
4 printf("%d\n", FOO);
5 }
so the replacement takes place in line 5, and not in line 1. hence the answer to your question is: once.
A #define'd macro invocation is expanded until there are no more terms to expand, except it doesn't recurse. For example:
#define TIMES *
#define factorial(n) ((n) == 0 ? 1 : (n) TIMES factorial((n)-1))
// Doesn't actually work, don't use.
Suppose you say factorial(2). It will expand to ((2) == 0 ? 1 : (2) * factorial((2)-1)). Note that factorial is expanded, then TIMES is also expanded, but factorial isn't expanded again afterwards, as that would be recursion.
However, note that nesting (arguably a different type of "recursion") is in fact expanded multiple times in the same expression:
#define ADD(a,b) ((a)+(b))
....
ADD(ADD(1,2),ADD(3,4)) // expands to ((((1)+(2)))+(((3)+(4))))