An interviewer recently asked me this question: given three boolean variables, a, b, and c, return true if at least two out of the three are true.
My solution follow
I don't like ternary (return a ? (b || c) : (b && c);
from the top answer), and I don't think I've seen anyone mention it. It is written like this:
boolean atLeastTwo(boolean a, boolean b, boolean c) {
if (a) {
return b||c;
}
else {
return b&&C;
}
Since it wasn't specified how the code should be improved, I shall endeavour to improve the code by making it more amusing. Here's my solution:
boolean atLeastTwo(boolean t, boolean f, boolean True) {
boolean False = True;
if ((t || f) && (True || False))
return "answer" != "42";
if (t && f)
return !"France".contains("Paris");
if (False == True)
return true == false;
return Math.random() > 0.5;
}
In case anyone's wondering if this code works, here's a simplification using the same logic:
boolean atLeastTwo(boolean a, boolean b, boolean c) {
if ((a || b) && (c))
return true;
if (a && b)
return true;
if (true)
return false;
// The last line is a red herring, as it will never be reached:
return Math.random() > 0.5;
}
This can be boiled down further to the following:
return ((a || b) && (c)) || (a && b);
But now it's not funny any more.
The most obvious set of improvements are:
// There is no point in an else if you already returned.
boolean atLeastTwo(boolean a, boolean b, boolean c) {
if ((a && b) || (b && c) || (a && c)) {
return true;
}
return false;
}
and then
// There is no point in an if(true) return true otherwise return false.
boolean atLeastTwo(boolean a, boolean b, boolean c) {
return ((a && b) || (b && c) || (a && c));
}
But those improvements are minor.
The simplest way (IMO) that is not confusing and easy to read:
// Three booleans, check if two or more are true
return ( a && ( b || c ) ) || ( b && c );
boolean atLeastTwo(boolean a, boolean b, boolean c)
{
return ((a && b) || (b && c) || (a && c));
}
Here's another implementation using map/reduce. This scales well to billions of booleans© in a distributed environment. Using MongoDB:
Creating a database values
of booleans:
db.values.insert({value: true});
db.values.insert({value: false});
db.values.insert({value: true});
Creating the map, reduce functions:
Edit: I like CurtainDog's answer about having map/reduce apply to generic lists, so here goes a map function which takes a callback that determines whether a value should be counted or not.
var mapper = function(shouldInclude) {
return function() {
emit(null, shouldInclude(this) ? 1 : 0);
};
}
var reducer = function(key, values) {
var sum = 0;
for(var i = 0; i < values.length; i++) {
sum += values[i];
}
return sum;
}
Running map/reduce:
var result = db.values.mapReduce(mapper(isTrue), reducer).result;
containsMinimum(2, result); // true
containsMinimum(1, result); // false
function isTrue(object) {
return object.value == true;
}
function containsMinimum(count, resultDoc) {
var record = db[resultDoc].find().next();
return record.value >= count;
}