Logic to test that 3 of 4 are True - boolean-logic

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):

Long but very simple, (disjuntive) normal form:
(~a & b & c & d) | (a & ~b & c & d) | (a & b & ~c & d) | (a & b & c & ~d)
It may be simplified but that requires more thinking :P

Not sure it is simpler, but maybe.
((x xor y) and (a and b)) or ((x and y) and (a xor b))

If you want to use this logic in a programming language, my suggestion is
bool test(bool a, bool b, bool c, bool d){
int n1 = a ? 1 : 0;
int n2 = b ? 1 : 0;
int n3 = c ? 1 : 0;
int n4 = d ? 1 : 0;
return n1 + n2 + n3 + n4 == 3;
}
Or if you want, you can put all of these in a single line:
return (a ? 1 : 0) + (b ? 1 : 0) + (C ? 1 : 0) + (d ? 1 : 0) == 3;
Also you can generalize this problem to n of m :
bool test(bool *values, int n, int m){
int sum = 0;
for(int i = 0; i < m; i += 1){
sum += values[i] ? 1 : 0;
}
return sum == n;
}

This answer depends on the system of representation, but if 0 is the only value interpreted as false, and not(false) always returns the same numeric value, then not(a) + not(b) + not(c) + not(d) = not(0) should do the trick.

Keeping in mind that SO if for programming questions, rather than mere logical problems, the answer obviously depends on the choice of a programming language. Some languages support features that are uncommon to others.
For example, in C++ you could test your conditions with:
(a + b + c + d) == 3
This should be the fastest way to do the check in languages that support automatic (low-level) conversion from boolean to integer types. But again, there is no general answer for that problem.

The best I can do is ((x ^ y) ^ (a ^ b)) && ((a || x) && (b || y))

((a xor b) xor (c xor d)) and ((a or b) and (c or d))
The fist expression searchs for 1 or 3 true's out of 4. The second one eliminates 0 or 1 (and sometimes 2) true's out of 4.

Java 8, filter out the false values, and count the remaining true values:
public static long count(Boolean... values) {
return Arrays.stream(values).filter(t -> t).count();
}
Then you can use it as follows:
if (3 == count(a, b, c, d)) {
System.out.println("There... are... THREE... lights!");
}
Easily generalizes to checking for n of m items being true.

To check at least n out of all Boolean are true, ( n must be less than or equal to total number of Boolean :p)
if (((a ? 1:0) + (b ? 1:0 ) + (c ? 1:0) + (d ? 1:0 )) >= n) {
// do the rest
}
Edit : After #Cruncher's comment
To check 3 boolean out of 4
if (((a ? 1:0) + (b ? 1:0 ) + (c ? 1:0) + (d ? 1:0 )) == 3) {
// do the rest
}
Another one :
((c & d) & (a ^ b)) | ((a & b) & (c ^ d)) (Details)

Here's a way you could solve it in C# with LINQ:
bool threeTrue = new[] { a, b, x, y }.Count(x => x) == 3;

That is the symmetric Boolean function S₃(4). A symmetric Boolean function is a boolean function which only depends on the quantity of inputs set, but doesn't depend on which inputs they are. Knuth mentions functions of this type in section 7.1.2 in Volume 4 of The Art of Computer Programming.
S₃(4) can be computed with 7 operations as follows:
(x && y && (a || b)) ^ ((x || y) && a && b)
Knuth shows that this is optimal, meaning that you cannot do this in less than 7 operations using the normal operators: &&, || , ^, <, and >.
However if you want to use this in a language which uses 1 for true and 0 for false, you can also use addition easily:
x + y + a + b == 3
which makes your intention quite clear.

(a && b && (c xor d)) || (c && d && (a xor b))
From a pure logic point of view this is what I came up with.
By the pigeon hole principle, if exactly 3 are true, then either a and b is true, or c and d is true. Then its just a matter of anding each of those cases with exactly one of the other 2.
Wolfram truth table

If you use a logic visualization tool like Karnaugh Maps, you see that this is a problem where you can't avoid a full blown logic term if you want to write it in one if (...) line. Lopina showed it already, it's not possible to write it simpler. You can factor out a bit, but it will stay hard to read for you AND for the machine.
Counting solutions are not bad and they show what you are really after. How you do the counting efficiently depends on your programming language. The array solutions with Python oder LinQ are nice to look at, but beware, this is SLOW. Wolf's (a+b+x+y)==3 will work nicely and fast, but only if your language equates "true" with 1. If "true" is represented by -1, you will have to test for -3 :)
If your language uses true booleans, you could try to program it explicitly (I use != as XOR test):
if (a)
{
if (b)
return (x != y); // a,b=true, so either x or y must be true
else
return (x && y); // a=true, b=false, so x AND y must be true
}
else
{
if (b)
return (x && y); // a=false, b=true, so x and y must be true
else
return false; // a,b false, can't get 3 of 4
}
"x != y" works only if x,y are of a boolean type. If they are some other type where 0 is false and everything else is true, this can fail. Then use a boolean XOR, or ( (bool)x != (bool)y ), or write "if (x) return (y==false) else return (y==true);", which is a bit more work for the computer.
If your programming language provides the ternary ?: operator, you can shorten it to
if (a)
return b ? (x != y) : (x && y);
else
return b ? (x && y) : false;
which keeps a bit of readability, or cut it aggressively to
return a ? (b ? (x != y) : (x && y)) : (b ? (x && y) : false);
This code does exactly three logic tests (state of a, state of b, comparison of x and y) and should be faster than most of the other answers here. But you need to comment it, or you won't understand it after 3 months :)

There are a lot of good answers here; here is an alternate formulation which no one else has posted yet:
a ? (b ? (c ^ d) : (c && d)) : (b && c && d)

Similar to the first answer, but pure Java:
int t(boolean b) {
return (b) ? 1 : 0;
}
if (t(x) + t(y) + t(a) + t(b) == 3) return true;
return false;
I prefer counting them as integers because it makes for more readable code.

In Python, to see how many of an iterable of elements are True, use sum (it's quite straightforward):
Setup
import itertools
arrays = list(itertools.product(*[[True, False]]*4))
Actual Test
for array in arrays:
print(array, sum(array)==3)
Output
(True, True, True, True) False
(True, True, True, False) True
(True, True, False, True) True
(True, True, False, False) False
(True, False, True, True) True
(True, False, True, False) False
(True, False, False, True) False
(True, False, False, False) False
(False, True, True, True) True
(False, True, True, False) False
(False, True, False, True) False
(False, True, False, False) False
(False, False, True, True) False
(False, False, True, False) False
(False, False, False, True) False
(False, False, False, False) False

If you're after the on-the-paper (non-programming) solution, then K-maps and Quine-McCluskey algorithms are what you're after, they help you minify your boolean function.
In your case, the result is
y = (x̄3 ^ x2 ^ x1 ^ x0) ∨ (x3 ^ x̄2 ^ x1 ^ x0) ∨ (x3 ^ x2 ^ x̄1 ^ x0) ∨ (x3 ^ x2 ^ x1 ^ x̄0)
If you want to do this programmatically, non-fixed amount of variables and a custom "threshold", then simply iterating thru a list of boolean values and counting occurrences of "true" is pretty simple and straightforward.

I want to return true if and only if 3 out of 4 boolean values are true.
Given the 4 boolean values, a, b, x, y, this task translates into the following C statement:
return (a+b+x+y) == 3;

((a^b)^(x^y))&((a|b)&(x|y))
is what you want. Basically I took your code and added checking if actually 3 are true and not 3 are false.

A programming question without an answer involving recursion? Inconceivable!
There are enough "exactly 3 out of 4 trues" answers, but here's a generalised (Java) version for "exactly m out of n trues" (otherwise recursion isn't really worth it) just because you can:
public static boolean containsTrues(boolean[] someBooleans,
int anIndex, int truesExpected, int truesFoundSoFar) {
if (anIndex >= someBooleans.length) {
return truesExpected == truesFoundSoFar; // reached end
}
int falsesExpected = someBooleans.length - truesExpected;
boolean currentBoolean = someBooleans[anIndex];
int truesFound = truesFoundSoFar + (currentBoolean ? 1 : 0);
if (truesFound > truesExpected) {
return false;
}
if (anIndex - truesFound > falsesExpected) {
return false; // too many falses
}
return containsTrues(someBooleans, anIndex + 1, truesExpected,
truesFound);
}
This could be called with something like:
boolean[] booleans = { true, false, true, true, false, true, true, false };
containsTrues(booleans, 0, 5, 0);
which should return true (because 5 of 8 values were true, as expected). Not quite happy with the words "trues" and "falses", but can't think of a better name right now.... Note that the recursion stops when too many true or too many false values have been found.

Since readability is a big concern, you could use a descriptive function call (wrapping any of the suggested implementations). If this calculation needs to be done in multiple places, a function call is the best way to achieve reuse, and makes it clear exactly what you are doing.
bool exactly_three_true_from(bool cond1, bool cond2, bool cond3, bool cond4)
{
//...
}

In PHP, making it more dynamic (just in case you change number of conditions, etc.):
$min = 6;
$total = 10;
// create our boolean array values
$arr = array_map(function($a){return mt_rand(0,1)>0;},range(1,$total));
// the 'check'
$arrbools = array_map(function($a){return (int)$a;},$arr);
$conditionMet = array_sum($arrbools)>=$min;
echo $conditionMet ? "Passed" : "Failed";

(((a AND b) OR (x AND y)) AND ((a XOR b) OR (x XOR y)))
While I could show that this is a good solution, Sam Hocevar's answer is easy both to write and understand later. In my book that makes it better.

Here is some c# code I just wrote because you have inspired me:
It takes any amount of arguments and will tell you if n of them are true.
static bool boolTester(int n, params bool[] values)
{
int sum = 0;
for (int i = 0; i < values.Length; i++)
{
if (values[i] == true)
{
sum += 1;
}
}
if( sum == n)
{
return true;
}
return false;
}
and you call it like so:
bool a = true;
bool b = true;
bool c = true;
bool d = false;
bool test = false;
test = boolTester(3, a, b, c, d);
So you can now test 7/9 or 15/100 as you will.

Related

Why idris2 can't proof that div 1 2 < 1 = True?

When I write:
div_1_2_lower_than_1 : div (S Z) 2 < (S Z) = True
div_1_2_lower_than_1 = Refl
I get error:
While processing right hand side of div_1_2_lower_than_1. Can't solve constraint
between: True and compare (1 `div` 2) 1 == LT.
Meanwhile when I write:
minus_1_2_lower_than_1 : minus (S Z) 2 < (S Z) = True
minus_1_2_lower_than_1 = Refl
Everything is fine.
Why?
Updated:
I used Data.Nat and natDiv for some reason fundamentally not validated.
div_1_2_eq_0 : div (S Z) (S (S Z)) = 0
div_1_2_eq_0 = Refl
Error:
While processing right hand side of div_1_2_eq_0. Can't solve constraint between: 0 and divNat 1 2.
I think this is right. The implementation of div isn't exported so the type checker can't reduce it
export partial
divNat : Nat -> Nat -> Nat
public export
Integral Nat where
div = divNat
You can try using divNatNZ instead, which is public exported, though for some reason it expects the non-zero proof explicitly.

I'm really confused about function declarations in Haskell

This is a homework, so I would prefer only tips or a link to where I can learn rather than a full answer. This is what I am given:
allEqual :: Eq a => a -> a -> a -> Bool
What I understand from this is that I am supposed to compare 3 values (in this case a, a, a?) and return whether or not they all equal one another. This is what I tried:
allEqual :: Eq a => a -> a -> a -> Bool
allEqual x y z do
Bool check <- x == y
Bool nextC <- y == z
if check == nextC
then True
else False
I honestly feel completely lost with Haskell, so any tips on how to read functions or declare them would help immensely.
This question already has several other perfectly good answers explaining how to solve your problem. I don’t want to do that; instead, I will go through each line of your code, progressively correct the problems, and hopefully help you understand Haskell a bit better.
First, I’ll copy your code for convenience:
allEqual :: Eq a => a -> a -> a -> Bool
allEqual x y z do
Bool check <- x == y
Bool nextC <- y == z
if check == nextC
then True
else False
The first line is the type signature; this is already explained well in other answers, so I’ll skip this and go on to the next line.
The second line is where you are defining your function. The first thing you’ve missed is that you need an equals sign to define a function: function definition syntax is functionName arg1 arg2 arg3 … = functionBody, and you can’t remove the =. So let’s correct that:
allEqual :: Eq a => a -> a -> a -> Bool
allEqual x y z = do
Bool check <- x == y
Bool nextC <- y == z
if check == nextC
then True
else False
The next error is using do notation. do notation is notorious for confusing beginners, so don’t feel bad about misusing it. In Haskell, do notation is only used in specific situations where it is necessary to execute a sequence of statements line by line, and especially when you have some side-effect (like, say, printing to the console) which is executed with each line. Clearly, this doesn’t fit here — all you’re doing is comparing some values and returning a result, which is hardly something which requires line-by-line execution. So let’s get rid of that do:
allEqual :: Eq a => a -> a -> a -> Bool
allEqual x y z =
let Bool check = x == y
Bool nextC = y == z
in
if check == nextC
then True
else False
(I’ve also replaced the <- binding with let … in …, since <- can only be used within a do block.)
Next, another problem: Bool check is not valid Haskell! You may be familiar with this syntax from other languages, but in Haskell, a type is always specified using ::, and often with a type signature. So I’ll remove Bool before the names and add type signatures instead:
allEqual :: Eq a => a -> a -> a -> Bool
allEqual x y z =
let check :: Bool
check = x == y
nextC :: Bool
nextC = y == z
in
if check == nextC
then True
else False
Now, at this point, your program is perfectly valid Haskell — you’ll be able to compile it, and it will work. But there’s still a few improvements you can make.
For a start, you don’t need to include types — Haskell has type inference, and in most cases it’s fine to leave types out (although it’s traditional to include them for functions). So let’s get rid of the types in the let:
allEqual :: Eq a => a -> a -> a -> Bool
allEqual x y z =
let check = x == y
nextC = y == z
in
if check == nextC
then True
else False
Now, check and nextC are only used in one place — giving them names doesn’t do anything, and only serves to make the code less readable. So I’ll inline the definitions of check and nextC into their usages:
allEqual :: Eq a => a -> a -> a -> Bool
allEqual x y z =
if (x == y) == (y == z)
then True
else False
Finally, I see you have an expression of the form if <condition> then True else False. This is redundant — you can simply return the <condition> with the same meaning. So let’s do that:
allEqual :: Eq a => a -> a -> a -> Bool
allEqual x y z = (x == y) == (y == z)
This is much, much better than the code you started with!
(There is actually one more improvement that you can make to this code. At this point, it should be obvious that your code has a bug. Can you find it? And if so, can you fix it? Hint: you can use the && operator to ‘and’ two booleans together.)
Lets start with a function that takes a single Int:
allEqual1Int :: Int -> Bool
allEqual1Int x = True
allEqual1Int' :: Int -> Bool
allEqual1Int' x =
if x == x
then True
else False
If we compare that to your line
allEqual x y z do
we notice that you miss a = and that you don't need a do.
A version for String could look like
allEqual1String' :: String -> Bool
allEqual1String' x =
if x == x
then True
else False
and we observe that the same implementation works for multiple types (Int and String) provided they support ==.
Now a is a type variable, think of it as a variable such that its value is a type. And the requirement that the given type supports == is encoded in the Eq a constraint (Think of it as an interface). Therefore
allEqual :: Eq a => a -> a -> a -> Bool
works for any such type that supports ==.
Haskell is a bit strange language for those who programmed in different languages before. Let's first have a look at this function:
allEqual :: Int -> Int -> Int -> Bool
You can look at this like that: the last "thing" after "->" is a return type. Previews "things" are parameters. From that, we know the function accepts three parameters that are Int and returns the Bool.
Now have a look at your function.
allEqual :: Eq a => a -> a -> a -> Bool
There is an extra syntax "Eq a =>". What it basically does is all the following "a" in declaration must implement Eq. So it is a more generalized version of the first function. It accepts three parameters that implement "Eq" and returns Bool. What the function should probably do is check if all values are equal.
Now let's have a look at your implementation. You are using a do syntax. I feel like it is not the best approach in the beginning. Let's implement a very similar function which checks if all parameters are equal to 3.
allEq3 :: Int -> Int -> Int -> Bool
allEq3 x y z = isEq3 x && isEq3 y && isEq3 z
where
isEq3 :: Int -> Bool
isEq3 x = x == 3
Like in your example, we have three parameters, and we return Bool. In the first line, we call function isEq3 on all the parameters. If all these calls return true allEq3 will also return true. Otherwise, the function will return false. Notice that the function isEq3 is defined below after the keyword "where". This is a very common thing in Haskell.
So what we did here is taking a big problem of checking if all the parameters are equal to 3 and divide it into smaller pieces which check whether a value is equal to 3.
You can improve this implementation a lot but I think this is the best way to take the first steps in Haskell. If you really want to learn this language you should have a look at this.
allEqual :: Eq a => a -> a -> a -> Bool
The signature says: allEqual consumes 3 values of type a; it produces a result of type Bool. The Eq a => part limits the possible operations a can have; it says whatever type a is, it needs to satisfy the requirements defined in Eq. You can find those requirements here: http://hackage.haskell.org/package/base-4.12.0.0/docs/Prelude.html#t:Eq
You now know what operations a can do, you can then complete your function by following the type signature.
Here's how you do it:
allEqual :: Eq a => a -> a -> a -> Bool
allEqual x y z = x == y && y == z
What does this mean?
The first line defines the function's type signature.
In human words, it would say something like:
There is a function called allEqual for any type a. It requires an instance of Eq a* and takes three parameters, all of type a, and returns a Bool
The second line says:
The function allEqual, for any parameters x, y, and z, should evaluate x == y && y == z, which simply compares that x equals y and y equals z.
* Instances or type classes are a language feature that not many other programming languages have, so if you're confused to what they mean I'd suggest learning about them first.

Construct circuit using only NAND and NOT GATES

In the image above, circuit is Sum of Products
(B’+D’) (A+D) (A+C)
The image below is my attempt on using NAND and NOT gates only. However, my senses is telling me that I am doing it wrongly. Please help!
The first circuit actually implements
which is this circuit:
Using De Morgan's Laws, this is equivalent to
which is this circuit:
This Python program can be used to compare the circuits:
import itertools
# Create all the possible input combinations
x = (True, False)
comb = set(itertools.product(x, x, x, x))
# AD + AC + B'D'
def c1(a, b, c, d):
return ((a and d) or (a and c) or ((not b) and (not d)))
# ((AD)'(AC)'(B'D')')'
def c2(a, b, c, d):
return not ((not (a and d)) and (not (a and c)) and (not ((not b) and (not d))))
# For each input, verify that the results are the same
for x in comb:
r1 = c1(*x)
r2 = c2(*x)
if r1 != r2:
print "Error: Input %s produced %s != %s" % (x, r1, r2)
You can replace all AND gates with NAND gates and just negate the result. I can see that you negated the inputs, which is wrong because:
(ab)' != a'b'
As an example think about signals (a, b) = (1, 0). If you negate them and calculate output, you get 0. If you first calculate and then negate output, you get 1.
About the OR gate:
a + b + c -> ((a + b + c)')' -> (a'b'c')'
So OR gate is NAND gate with all signals negated.

In Lua, how to set a nil parameter to some default value correctly?

For Lua code below:
local function foo(x, y, z)
local x = x or true
local y = y or 1234
z = z or "default"
end
I always thought the meaning of these three lines inside the function is:
If x/y/z is nil, x/y/z is set to true/1234/"default". Otherwise, it remains whatever it is. Therefore, I have such a line in many places to set a parameter to some default value in case it might be passed into a function as nil.
However, it seems not totally correct in my experiments. I am not sure where I learnt this Lua coding concept. How to do it correctly?
The method will work as long as your boolean(?) variable x was not initialised as false. If you only want to use defaults against nil values, the a or b method is correct.
If your variable can be false, you'd have to use a strict if-then block:
if x == nil then x = true end
You can see a few more methods/examples about ternary operators on lua wiki.
There exists one more strict method if you want to be able pass nil as argument(e.g. you want distinguish foo(1,2,nil) and foo(1,2))
function foo(...)
local n,x,y,z = select('#', ...), ...
if n < 3 then z = default end
if n < 2 then y = default end
if n < 1 then x = default end
-- here x,y or z can be nil
...
end
But you have to be shure you know what you doing because it may be not expected behavior for users of your function.
This should work as expected:
function foo(x, y, z)
x = (x == nil) or x
y = (y == nil and 1234) or y
z = (z == nil and "default") or z
print(x, y, z)
end
> foo()
true 1234 default
> foo(false, false, "me")
false false me
> foo(nil, 50, "me")
true 50 me

Code Golf: Lights out

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
The challenge
The shortest code by character count to solve the input lights out board.
The lights out board is a 2d square grid of varying size composed of two characters - . for a light that is off and * for a light that is on.
To solve the board, all "lights" have to be turned off. Toggling a light (i.e. turning off when it is on, turning on when it is off) is made 5 lights at a time - the light selected and the lights surround it in a + (plus) shape.
"Selecting" the middle light will solve the board:
.*.
***
.*.
Since Lights Out! solution order does not matter, the output will be a new board with markings on what bulbs to select. The above board's solution is
...
.X.
...
Turning off a light in a corner where there are no side bulbs to turn off will not overflow:
...
..*
.**
Selecting the lower-right bulb will only turn off 3 bulbs in this case.
Test cases
Input:
**.**
*.*.*
.***.
*.*.*
**.**
Output:
X...X
.....
..X..
.....
X...X
Input:
.*.*.
**.**
.*.*.
*.*.*
*.*.*
Output:
.....
.X.X.
.....
.....
X.X.X
Input:
*...*
**.**
..*..
*.*..
*.**.
Output:
X.X.X
..X..
.....
.....
X.X..
Code count includes input/output (i.e full program).
Perl, 172 characters
Perl, 333 251 203 197 190 172 characters. In this version, we randomly push buttons until all of the lights are out.
map{$N++;$E+=/\*/*1<<$t++for/./g}<>;
$C^=$b=1<<($%=rand$t),
$E^=$b|$b>>$N|($%<$t-$N)*$b<<$N|($%%$N&&$b/2)|(++$%%$N&&$b*2)while$E;
die map{('.',X)[1&$C>>$_-1],$_%$N?"":$/}1..$t
Haskell, 263 characters (277 and 285 before edit) (according to wc)
import List
o x=zipWith4(\a b c i->foldr1(/=)[a,b,c,i])x(f:x)$tail x++[f]
f=0>0
d t=mapM(\_->[f,1>0])t>>=c t
c(l:m:n)x=map(x:)$c(zipWith(/=)m x:n)$o x l
c[k]x=[a|a<-[[x]],not$or$o x k]
main=interact$unlines.u((['.','X']!!).fromEnum).head.d.u(<'.').lines
u=map.map
This includes IO code : you can simply compile it and it works.
This method use the fact that once the first line of the solution is determined, it is easy to determine what the other lines should look like. So we try every solution for the first line, and verify that the all lights are off on the last line, and this algorithm is O(n²*2^n)
Edit : here is an un-shrunk version :
import Data.List
-- xor on a list. /= works like binary xor, so we just need a fold
xor = foldr (/=) False
-- what will be changed on a line when we push the buttons :
changeLine orig chg = zipWith4 (\a b c d -> xor [a,b,c,d]) chg (False:chg) (tail chg ++ [False]) orig
-- change a line according to the buttons pushed one line higher :
changeLine2 orig chg = zipWith (/=) orig chg
-- compute a solution given a first line.
-- if no solution is given, return []
solution (l1:l2:ls) chg = map (chg:) $ solution (changeLine2 l2 chg:ls) (changeLine l1 chg)
solution [l] chg = if or (changeLine l chg) then [] else [[chg]]
firstLines n = mapM (const [False,True]) [1..n]
-- original uses something equivalent to "firstLines (length gris)", which only
-- works on square grids.
solutions grid = firstLines (length $ head grid) >>= solution grid
main = interact $ unlines . disp . head . solutions . parse . lines
where parse = map (map (\c ->
case c of
'.' -> False
'*' -> True))
disp = map (map (\b -> if b then 'X' else '.'))
Ruby, 225 221
b=$<.read.split
d=b.size
n=b.join.tr'.*','01'
f=2**d**2
h=0
d.times{h=h<<d|2**d-1&~1}
f.times{|a|e=(n.to_i(2)^a^a<<d^a>>d^(a&h)>>1^a<<1&h)&f-1
e==0&&(i=("%0*b"%[d*d,a]).tr('01','.X')
d.times{puts i[0,d]
i=i[d..-1]}
exit)}
F#, 672 646 643 634 629 628 chars (incl newlines)
EDIT: priceless: this post triggered Stackoverflow's human verification system. I bet it's because of the code.
EDIT2: more filthy tricks knocked off 36 chars. Reversing an if in the second line shaved off 5 more.
Writing this code made my eyes bleed and my brain melt.
The good: it's short(ish).
The bad: it'll crash on any input square larger than 4x4 (it's an O(be stupid and try everything) algorithm, O(n*2^(n^2)) to be more precise). Much of the ugliness comes from padding the input square with zeroes on all sides to avoid edge and corner cases.
The ugly: just look at it. It's code only a parent could love. Liberal uses of >>> and <<< made F# look like brainfuck.
The program accepts rows of input until you enter a blank line.
This code doesn't work in F# interactive. It has to be compiled inside a project.
open System
let rec i()=[let l=Console.ReadLine()in if l<>""then yield!l::i()]
let a=i()
let m=a.[0].Length
let M=m+2
let q=Seq.sum[for k in 1..m->(1L<<<m)-1L<<<k*M+1]
let B=Seq.sum(Seq.mapi(fun i s->Convert.ToInt64(String.collect(function|'.'->"0"|_->"1")s,2)<<<M*i+M+1)a)
let rec f B x=function 0L->B&&&q|n->f(if n%2L=1L then B^^^(x*7L/2L+(x<<<M)+(x>>>M))else B)(x*2L)(n/2L)
let z=fst<|Seq.find(snd>>(=)0L)[for k in 0L..1L<<<m*m->let n=Seq.sum[for j in 0..m->k+1L&&&(((1L<<<m)-1L)<<<j*m)<<<M+1+2*j]in n,f B 1L n]
for i=0 to m-1 do
for j=0 to m-1 do printf"%s"(if z&&&(1L<<<m-j+M*i+M)=0L then "." else "X")
printfn""
F#, 23 lines
Uses brute force and a liberal amount of bitmasking to find a solution:
open System.Collections
let solve(r:string) =
let s = r.Replace("\n", "")
let size = s.Length|>float|>sqrt|>int
let buttons =
[| for i in 0 .. (size*size)-1 do
let x = new BitArray(size*size)
{ 0 .. (size*size)-1 } |> Seq.iter (fun j ->
let toXY n = n / size, n % size
let (ir, ic), (jr, jc) = toXY i, toXY j
x.[j] <- ir=jr&&abs(ic-jc)<2||ic=jc&&abs(ir-jr)<2)
yield x |]
let testPerm permutation =
let b = new BitArray(s.Length)
s |> Seq.iteri (fun i x -> if x = '*' then b.[i] <- true)
permutation |> Seq.iteri (fun i x -> if x = '1' then b.Xor(buttons.[i]);() )
b |> Seq.cast |> Seq.forall (fun x -> not x)
{for a in 0 .. (1 <<< (size * size)) - 1 -> System.Convert.ToString(a, 2).PadLeft(size * size, '0') }
|> Seq.pick (fun p -> if testPerm p then Some p else None)
|> Seq.iteri (fun i s -> printf "%s%s" (if s = '1' then "X" else ".") (if (i + 1) % size = 0 then "\n" else "") )
Usage:
> solve ".*.
***
.*.";;
...
.X.
...
val it : unit = ()
> solve "**.**
*.*.*
.***.
*.*.*
**.**";;
..X..
X.X.X
..X..
X.X.X
..X..
val it : unit = ()
> solve "*...*
**.**
..*..
*.*..
*.**.";;
.....
X...X
.....
X.X.X
....X
C89, 436 characters
Original source (75 lines, 1074 characters):
#include <stdio.h>
#include <string.h>
int board[9][9];
int zeroes[9];
char presses[99];
int size;
int i;
#define TOGGLE { \
board[i][j] ^= 4; \
if(i > 0) \
board[i-1][j] ^= 4; \
if(j > 0) \
board[i][j-1] ^= 4; \
board[i+1][j] ^= 4; \
board[i][j+1] ^= 4; \
presses[i*size + i + j] ^= 118; /* '.' xor 'X' */ \
}
void search(int j)
{
int i = 0;
if(j == size)
{
for(i = 1; i < size; i++)
{
for(j = 0; j < size; j++)
{
if(board[i-1][j])
TOGGLE
}
}
if(memcmp(board[size - 1], zeroes, size * sizeof(int)) == 0)
puts(presses);
for(i = 1; i < size; i++)
{
for(j = 0; j < size; j++)
{
if(presses[i*size + i + j] & 16)
TOGGLE
}
}
}
else
{
search(j+1);
TOGGLE
search(j+1);
TOGGLE
}
}
int main(int c, char **v)
{
while((c = getchar()) != EOF)
{
if(c == '\n')
{
size++;
i = 0;
}
else
board[size][i++] = ~c & 4; // '.' ==> 0, '*' ==> 4
}
memset(presses, '.', 99);
for(c = 1; c <= size; c++)
presses[c * size + c - 1] = '\n';
presses[size * size + size] = '\0';
search(0);
}
Compressed source, with line breaks added for your sanity:
#define T{b[i][j]^=4;if(i)b[i-1][j]^=4;if(j)b[i][j-1]^=4;b[i+1][j]^=4;b[i][j+1]^=4;p[i*s+i+j]^=118;}
b[9][9],z[9],s,i;char p[99];
S(j){int i=0;if(j-s){S(j+1);T S(j+1);T}else{
for(i=1;i<s;i++)for(j=0;j<s;j++)if(b[i-1][j])T
if(!memcmp(b[s-1],z,s*4))puts(p);
for(i=1;i<s;i++)for(j=0;j<s;j++)if(p[i*s+i+j]&16)T}}
main(c){while((c=getchar())+1)if(c-10)b[s][i++]=~c&4;else s++,i=0;
memset(p,46,99);for(c=1;c<=s;c++)p[c*s+c-1]=10;p[s*s+s]=0;S(0);}
Note that this solution assumes 4-byte integers; if integers are not 4 bytes on your system, replace the 4 in the call to memcmp with your integer size. The maximum sized grid this supports is 8x8 (not 9x9, since the bit flipping ignores two of the edge cases); to support up to 98x98, add another 9 to the array sizes in the declarations of b, z and p and the call to memset.
Also note that this finds and prints ALL solutions, not just the first solution. Runtime is O(2^N * N^2), where N is the size of the grid. The input format must be perfectly valid, as no error checking is performed -- it must consist of only ., *, and '\n', and it must have exactly N lines (i.e. the last character must be a '\n').
Ruby:
class Array
def solve
carry
(0...(2**w)).each {|i|
flip i
return self if solved?
flip i
}
end
def flip(i)
(0...w).each {|n|
press n, 0 if i & (1 << n) != 0
}
carry
end
def solved?
(0...h).each {|y|
(0...w).each {|x|
return false if self[y][x]
}
}
true
end
def carry
(0...h-1).each {|y|
(0...w).each {|x|
press x, y+1 if self[y][x]
}
}
end
def h() size end
def w() self[0].size end
def press x, y
#presses = (0...h).map { [false] * w } if #presses == nil
#presses[y][x] = !#presses[y][x]
inv x, y
if y>0 then inv x, y-1 end
if y<h-1 then inv x, y+1 end
if x>0 then inv x-1, y end
if x<w-1 then inv x+1, y end
end
def inv x, y
self[y][x] = !self[y][x]
end
def presses
(0...h).each {|y|
puts (0...w).map {|x|
if #presses[y][x] then 'X' else '.' end
}.inject {|a,b| a+b}
}
end
end
STDIN.read.split(/\n/).map{|x|x.split(//).map {|v|v == '*'}}.solve.presses
Lua, 499 characters
Fast, uses Strategy to find a quicker solution.
m={46,[42]=88,[46]=1,[88]=42}o={88,[42]=46,[46]=42,[88]=1}z={1,[42]=1}r=io.read
l=r()s=#l q={l:byte(1,s)}
for i=2,s do q[#q+1]=10 l=r()for j=1,#l do q[#q+1]=l:byte(j)end end
function t(p,v)q[p]=v[q[p]]or q[p]end
function u(p)t(p,m)t(p-1,o)t(p+1,o)t(p-s-1,o)t(p+s+1,o)end
while 1 do e=1 for i=1,(s+1)*s do
if i>(s+1)*(s-1)then if z[q[i]]then e=_ end
elseif z[q[i]]then u(i+s+1)end end
if e then break end
for i=1,s do if 42==q[i]or 46==q[i]then u(i)break end u(i)end end
print(string.char(unpack(q)))
Example input:
.....
.....
.....
.....
*...*
Example output:
XX...
..X..
X.XX.
X.X.X
...XX
Some of these have multiple answers. This seems to work but it's not exactly fast.
Groovy: 790 chracters
bd = System.in.readLines().collect{it.collect { it=='*'}}
sl = bd.collect{it.collect{false}}
println "\n\n\n"
solve(bd, sl, 0, 0, 0)
def solve(board, solution, int i, int j, prefix) {
/* println " ".multiply(prefix) + "$i $j"*/
if(done(board)) {
println sl.collect{it.collect{it?'X':'.'}.join("")}.join("\n")
return
}
if(j>=board[i].size) {
j=0; i++
}
if(i==board.size) {
return
}
solve(board, solution, i, j+1, prefix+1)
flip(solution, i, j)
flip(board, i, j)
flip(board, i+1, j)
flip(board, i-1, j)
flip(board, i, j+1)
flip(board, i, j-1)
solve(board, solution, i, j+1, prefix+1)
}
def flip(board, i, j) {
if(i>=0 && i<board.size && j>=0 && j<board[i].size)
board[i][j] = !board[i][j]
}
def done(board) {
return board.every { it.every{!it} }
}
For Haskell, here's a 406 376 342 character solution, though I'm sure there's a way to shrink this. Call the s function for the first solution found:
s b=head$t(b,[])
l=length
t(b,m)=if l u>0 then map snd u else concat$map t c where{i=[0..l b-1];c=[(a b p,m++[p])|p<-[(x,y)|x<-i,y<-i]];u=filter((all(==False)).fst)c}
a b(x,y)=foldl o b[(x,y),(x-1,y),(x+1,y),(x,y-1),(x,y+1)]
o b(x,y)=if x<0||y<0||x>=r||y>=r then b else take i b++[not(b!!i)]++drop(i+1)b where{r=floor$sqrt$fromIntegral$l b;i=y*r+x}
In its more-readable, typed form:
solution :: [Bool] -> [(Int,Int)]
solution board = head $ solutions (board, [])
solutions :: ([Bool],[(Int,Int)]) -> [[(Int,Int)]]
solutions (board,moves) =
if length solutions' > 0
then map snd solutions'
else concat $ map solutions candidates
where
boardIndices = [0..length board - 1]
candidates = [
(applyMove board pair, moves ++ [pair])
| pair <- [(x,y) | x <- boardIndices, y <- boardIndices]]
solutions' = filter ((all (==False)) . fst) candidates
applyMove :: [Bool] -> (Int,Int) -> [Bool]
applyMove board (x,y) =
foldl toggle board [(x,y), (x-1,y), (x+1,y), (x,y-1), (x,y+1)]
toggle :: [Bool] -> (Int,Int) -> [Bool]
toggle board (x,y) =
if x < 0 || y < 0 || x >= boardSize || y >= boardSize then board
else
take index board ++ [ not (board !! index) ]
++ drop (index + 1) board
where
boardSize = floor $ sqrt $ fromIntegral $ length board
index = y * boardSize + x
Note that this is a horrible breadth-first, brute-force algorithm.
F#, 365 370, 374, 444 including all whitespace
open System
let s(r:string)=
let d=r.IndexOf"\n"
let e,m,p=d+1,r.ToCharArray(),Random()
let o b k=m.[k]<-char(b^^^int m.[k])
while String(m).IndexOfAny([|'*';'\\'|])>=0 do
let x,y=p.Next d,p.Next d
o 118(x+y*e)
for i in x-1..x+1 do for n in y-1..y+1 do if i>=0&&i<d&&n>=0&&n<d then o 4(i+n*e)
printf"%s"(String m)
Here's the original readable version before the xor optimization. 1108
open System
let solve (input : string) =
let height = input.IndexOf("\n")
let width = height + 1
let board = input.ToCharArray()
let rnd = Random()
let mark = function
| '*' -> 'O'
| '.' -> 'X'
| 'O' -> '*'
| _ -> '.'
let flip x y =
let flip = function
| '*' -> '.'
| '.' -> '*'
| 'X' -> 'O'
| _ -> 'X'
if x >= 0 && x < height && y >= 0 && y < height then
board.[x + y * width] <- flip board.[x + y * width]
let solved() =
String(board).IndexOfAny([|'*';'O'|]) < 0
while not (solved()) do
let x = rnd.Next(height) // ignore newline
let y = rnd.Next(height)
board.[x + y * width] <- mark board.[x + y * width]
for i in -1..1 do
for n in -1..1 do
flip (x + i) (y + n)
printf "%s" (String(board))
Python — 982
Count is 982 not counting tabs and newlines. This includes necessary spaces. Started learning python this week, so I had some fun :). Pretty straight forward, nothing fancy here, besides the crappy var names to make it shorter.
import re
def m():
s=''
while 1:
y=raw_input()
if y=='':break
s=s+y+'\n'
t=a(s)
t.s()
t.p()
class a:
def __init__(x,y):
x.t=len(y);
r=re.compile('(.*)\n')
x.z=r.findall(y)
x.w=len(x.z[0])
x.v=len(x.z)
def s(x):
n=0
for i in range(0,x.t):
if(x.x(i,0)):
break
def x(x,d,c):
b=x.z[:]
for i in range(1,x.v+1):
for j in range(1,x.w+1):
if x.c():
break;
x.z=b[:]
x.u(i,j)
if d!=c:
x.x(d,c+1)
if x.c():
break;
if x.c():
return 1
x.z=b[:]
return 0;
def y(x,r,c):
e=x.z[r-1][c-1]
if e=='*':
return '.'
elif e=='x':
return 'X'
elif e=='X':
return 'x'
else:
return '*'
def j(x,r,c):
v=x.y(r+1,c)
x.r(r+1,c,v)
def k(x,r,c):
v=x.y(r-1,c)
x.r(r-1,c,v)
def h(x,r,c):
v=x.y(r,c-1)
x.r(r,c-1,v)
def l(x,r,c):
v=x.y(r,c+1)
x.r(r,c+1,v)
def u(x,r,c):
e=x.z[r-1][c-1]
if e=='*' or e=='x':
v='X'
else:
v='x'
x.r(r,c,v)
if r!=1:
x.k(r,c)
if r!=x.v:
x.j(r,c)
if c!=1:
x.h(r,c)
if c!=x.w:
x.l(r,c)
def r(x,r,c,l):
m=x.z[r-1]
m=m[:c-1]+l+m[c:]
x.z[r-1]=m
def c(x):
for i in x.z:
for j in i:
if j=='*' or j=='x':
return 0
return 1
def p(x):
for i in x.z:
print i
print '\n'
if __name__=='__main__':
m()
Usage:
*...*
**.**
..*..
*.*..
*.**.
X.X.X
..X..
.....
.....
X.X..