Finding minimum number of presses to shut down lamps - algorithm

I tried to solve a programming problem but my I was unable to see an efficient algorithm. Situation is like this: We have a set of n lamps which can be on (1) or off (0) like this: 1110001011101. That byte string means that there are 13 lamps forming a circle where first three lamps are on, then 3 next off and so on and circle mean that the last lamp is next to the first one.
Then we have been given an integer m>0. It means that in any turn we can choose a lamp and then it and its m adjacent lamps changes their state s to 1-s. I.e. if m=2 and lamp states are 1110001011101 then applying the process to the first lamp we get the sequence 0000001011110.
Now the question is that if the string of length about 2200 and m about 110 are fixed, how one can develop an algorithm that shut downs all the lamps with minimum number of turns?

This problem is similar to the well-known "lights out" problem. http://en.wikipedia.org/wiki/Lights_Out_%28game%29 One way to approach it is by using linear algebra. It's easier to understand with smaller numbers, say length = 5 and m = 1.
First note that choosing a lamp and changing it (and its neighbors') state twice has no effect. Second note that the order in which lamps (and their neighbors) are switch doesn't matter. So a strategy is just a set of lamps. We'll represent lamps that are chosen to be part of the strategy by 1 and lamps that are not chosen by 0. We place the 1's and 0's in a column vector, e.g., (0 1 1 0 1)^T where T is for transpose (rows become columns). That strategy means toggle the lamp in position 1 (starting at position 0, of course) and its two neighbors; then the lamp in position 2 and its two neighbors, and finally the lamp in position 4 and its two neighbors.
The effect of a strategy can be calculated by matrix multiplication over the field GF(2). GF(2) has just 2 elements, 0 and 1, with ordinary rules of arithmetic except for the rule 1 + 1 = 0. Then the effect of the strategy above is the result of matrix multiplication by a matrix with the result of choosing lamp i in the i-th column, in other words by a "circulant matrix` as follows:
[ 1 1 0 0 1 ] [0] [0]
[ 1 1 1 0 0 ] [1] [0]
[ 0 1 1 1 0 ] [1] = [0]
[ 0 0 1 1 1 ] [0] [0]
[ 1 0 0 1 1 ] [1] [1]
The result of the strategy (0 1 1 0 1)^T is to toggle only the light in the last position. So if you start with only the light in the last position lit, and apply the strategy, all the lights will be off.
In this simple case, we represent the initial configuration by a column vector b. The solution strategy is then a column vector x satisfying the matrix equation Ax = b.
The question now becomes, for given b, 1) is there an x satisfying Ax=b? 2) Is the solution x unique? If not, which x has the least 1's? 3) How can it be calculated?
The answers to the above questions will depend on the numbers "length" and "m" for the particular problem at hand. In the length = 5, m = 1 problem considered above, the theory of linear algebra tells us that there is a unique solution for any b. We can get solutions for b of the form (0 0 ... 1 ... 0)^T, in other words one 1 and the rest zero, by "rotating" the solution (0 1 1 0 1)^T. We can represent any solution uniquely as a linear combination of those solutions, so the strategy/solution with the minimum number of 1's is the same as the unique solution for any given initial state.
On the other hand, with length = 6 and m = 1, all three strategies (100100)^T, (010010)^T, and (001001)^T map to outcome (111111)^T, so that there is not a unique solution in some cases; by the theory of linear algebra, it follows that there is no solution in some other cases.
In general, we can tell whether solutions exist and are unique using Gaussian elimination. In the 5x5 case above, add row 0 to rows 1 and 4;
[ 1 1 0 0 1 ] [1 0 0 0 0] [ 1 1 0 0 1 ] [1 0 0 0 0]
[ 1 1 1 0 0 ] [0 1 0 0 0] [ 0 0 1 0 1 ] [1 1 0 0 0]
[ 0 1 1 1 0 ] [0 0 1 0 0] -> [ 0 1 1 1 0 ] [0 0 1 0 0] ->
[ 0 0 1 1 1 ] [0 0 0 1 0] [ 0 0 1 1 1 ] [0 0 0 1 0]
[ 1 0 0 1 1 ] [0 0 0 0 1] [ 0 1 0 1 0 ] [1 0 0 0 1]
then swap rows 1 and 2; then add row 1 to row 0 and row 4,
[ 1 1 0 0 1 ] [1 0 0 0 0] [ 1 0 1 1 1 ] [1 0 1 0 0]
[ 0 1 1 1 0 ] [0 0 1 0 0] [ 0 1 1 1 0 ] [0 0 1 0 0]
[ 0 0 1 0 1 ] [1 1 0 0 0] -> [ 0 0 1 0 1 ] [1 1 0 0 0] ->
[ 0 0 1 1 1 ] [0 0 0 1 0] [ 0 0 1 1 1 ] [0 0 0 1 0]
[ 0 1 0 1 0 ] [1 0 0 0 1] [ 0 0 1 0 0 ] [1 0 1 0 1]
then add row 2 to rows 0, 1, 3, 4; then add row 3 to rows 1, 2;
[ 1 0 0 1 0 ] [0 1 1 0 0] [ 1 0 0 0 0 ] [1 0 1 1 0]
[ 0 1 0 1 1 ] [1 1 1 0 0] [ 0 1 0 0 1 ] [0 0 1 1 0]
[ 0 0 1 0 1 ] [1 1 0 0 0] -> [ 0 0 1 0 1 ] [1 1 0 0 0] ->
[ 0 0 0 1 0 ] [1 1 0 1 0] [ 0 0 0 1 0 ] [1 1 0 1 0]
[ 0 0 0 0 1 ] [0 1 1 0 1] [ 0 0 0 0 1 ] [0 1 1 0 1]
and finally add row 4 to rows 1, 2:
[ 1 0 0 0 0 ] [1 0 1 1 0]
[ 0 1 0 0 0 ] [0 1 0 1 1]
[ 0 0 1 0 0 ] [1 0 1 0 1]
[ 0 0 0 1 0 ] [1 1 0 1 0]
[ 0 0 0 0 1 ] [0 1 1 0 1]
You can read off the basis of solutions in the columns of the right matrix. For example, the solution we used above is in the last column of the right matrix.
You should try Gaussian elimination in the length = 6, m = 1 case discussed above to see what happens.
In the given case (length = 2200, m = 110), I suspect that solutions always exist and are unique because the number of lamps toggled in one move is 221, which is relatively prime to 2200, but I suggest you use Gaussian elimination to find an explicit strategy for any starting position b. How would you minimize the number of moves if there were not a unique strategy?

There's a general solution to flipping problems like this using linear algebra over Z/2Z (that is the field containing only the numbers 0 and 1).
Suppose there's N bulbs and N switches. Let M be an N by N matrix with a 1 in position i, j if pressing switch i toggles bulb j. Here your matrix will look like this for N=5, m=1:
1, 1, 0, 0, 1
1, 1, 1, 0, 0
0, 1, 1, 1, 0
0, 0, 1, 1, 1
1, 0, 0, 1, 1
Let x be a column vector of size N, where each entry is 0 or 1.
Then Mx (that is, the product of the matrix M and the vector x over Z/2Z) is a column vector of size N which is the result of pressing the switches corresponding to 1s in x. That's because in Z/2Z, multiplication is like "and" and addition is like "xor".
Let v be a column vector of size N, with v_i=1 if bulb i is initially lit. Then x solves the problem if it's a solution to the linear system Mx = v. It can be solved, for example, using gaussian elimination.

Well, your explanation doesn't make it clear if the lamps should be only turned off or "flipped" (i.e., 0's become 1's and 1's become 0's). Your example data just turns them off.
If that's the case, just set the 110 lamps to 0 - that would be quicker than querying their state before switching them off. Assuming your lamps are in an array called "lamps" and the starting lamp position is startPos:
// These first 2 lines added after Kolmar remark about adjacent lamps meaning lamps to the left and right.
startPos = startPos - m;
if (startPos < 0) startPos += lamps.length;
for (int i=0; i <= m + 1; i++){
if ((i + startPos) > lamps.length) startPos = 0;
lamps[i + startPos] = 0;
}
If you need to "flip" the lamp's state, change the last line of the loop to:
lamps[i + startPos] = 1-lamps[i + startPos];

Related

Fill an n*n array with 1s and 0s

So Im trying to fill in array with 1s and 0s given the number of elements in each row and column.
for example if i have been given
int Row = {2, 2, 2, 3};
int Column = { 3, 2, 1, 3};
then a possible solution is
1 0 0 1
1 1 0 0
0 0 1 1
1 1 0 1
secondly is there any combination in which a valid solution is not possible even if the sum of both arrays (column and row) are equal. In my case it should be valid because 3+2+1+3=2+2+2+3 but is there any case in which both the sums are equal but there still doesn't exist a stable combination.
The answer i found was a greedy approach in which answer each subproblem. So i go column by column and fill in each column depending on the weight of the row.
Remember indexing start with 0
I start with column 0
since row 3 has the highest value (3) i fill it
0 0 0 0
0 0 0 0
0 0 0 0
1 0 0 0
now the row and column array are as follows
row = {2,2,2,2}
column = {2,2,1,3}
i keep filling until i can no longer insert more i.e column[0]=0
1 0 0 0
0 0 0 0
0 0 0 0
1 0 0 0
row = {1,2,2,2}
column={2,2,1,2}
1 0 0 0
1 0 0 0
0 0 0 0
1 0 0 0
row = {1,1,2,2}
column={2,1,1,2}
now since column[0]==0 i can go to the next column and perform the same procedure again

Find maximum covered elements without block by obstacles in path

Given MXN matrix where matrix elements are either "." or "*". Where . is representing road and * is representing block or wall. Person can move adjacent forward, down and diagonally, we need to find maximum "." covered by person without blocked by wall. Example(in image)
Can you please suggest me efficient algorithm to approach this problem?
You have to do this: https://en.wikipedia.org/wiki/Flood_fill
Take the biggest flood you can do.
You go through your matrix and find a '.'
Do a flood from that point. The amount of elements you flood the area you always compare it with the maximum you already found. To make this easy you can flood with a letter or a number or whatever you want but not with '.'. What you add instead of '.' consider it as a wall or a '*' so you don't try to flood that area again and again.
Continue to go through the matrix and try to find the next '.'. All the previous '.' where flooded so you won't consider the same area twice.
Redo 2 until you can't find any more '.'. The maximum will contain your answer.
When you have the answer you can go back in the Matrix and you already know the letter or number you flooded the area with the maximum result so you can print the biggest area.
Are you looking for the exact path or only the number of cases?
Edit: here a smallp Python script which creates a random matrix and count the number of cases in each zone defined by your "walls".
import numpy as np
matrix = np.random.randint(2, size=(10, 10))
print(matrix)
M, N = matrix.shape
walked = []
zonesCount = []
def pathCount(x, y):
if x < 0 or y < 0 or x >= M or y >= N:
return 0
if matrix[x, y] == 1: # I replaced * by 1 and . by 0 for easier generation
return 0
if (x, y) in walked:
return 0
walked.append((x, y))
count = 1
for i in [x - 1, x, x + 1]:
for j in [y - 1, y, y + 1]:
if (i, j) != (x, y):
count += pathCount(i, j)
return count
for x in range(M):
for y in range(N):
if not (x, y) in walked:
zonesCount.append(pathCount(x, y))
print('Max zone count :', max(zonesCount))
And here is the result:
[[0 0 1 0 0 0 1 0 1 0]
[1 0 1 0 0 0 1 0 1 1]
[0 1 0 0 1 0 0 1 1 1]
[0 0 1 0 0 0 1 1 0 1]
[1 0 1 1 1 1 0 1 1 0]
[1 0 1 1 1 1 0 1 1 0]
[0 0 0 1 1 1 0 0 0 0]
[1 0 0 1 1 0 0 1 1 0]
[0 1 0 1 0 0 1 0 1 1]
[0 1 1 0 0 0 1 0 1 0]]
Max zone count : 50

Fast index mapping in matlab

I have the following problem:
Given a matrix A
A = [ 1 2 2 3 3 ;
2 2 2 7 9 ]
where the sequence of unique numbers within the matrix is not continuous. In this example
unique(A) = [ 1 2 3 7 9 ]. % [ 4 5 6 8 ] are missing
I want to compute the same matrix, but using instead a continuous sequence, such that
unique(A_new) = [ 1 2 3 4 5 ];
I came up with the following solution
T = [ unique(A), [ 1:numel(unique(A)) ]' ];
A_new = zeros(size(A));
for i = 1:size(T,1)
A_new( A == T(i,1) ) = T(i,2);
end
This is incredibly slow: the size of the matrix A I have to work with is 200x400x300 and the the number of unique elements within this matrix is 33406.
Any idea on how to speed up the procedure?
If I understand correctly, in your example you want:
A_new = [ 1 2 2 3 3 ;
2 2 2 4 5 ]
So just compute a lookup table (lookup) such that you can then do:
A_new = lookup(A);
So in your case, lookup would be:
[ 1 2 3 0 0 0 4 0 5 ]
I'll leave the process for generating that as an exercise for the reader.
Approach 1 (not recommended)
This should be pretty fast, but it uses more memory:
[~, A_new] = max(bsxfun(#eq, A(:).', unique(A(:))));
A_new = reshape(A_new, size(A));
How does this work?
First A is linearized into a vector (A(:)). Also, a vector containing the unique values of A is computed (unique(A(:))). From those two vectors a matrix is generated (with bsxfun) in which each entry of A is compared to each of the unique values. That way, for each entry of A we know if it equals the first unique value, or the second unique value, etc. For the A given in your question, that matrix is
1 0 0 0 0 0 0 0 0 0
0 1 1 1 1 1 0 0 0 0
0 0 0 0 0 0 1 0 1 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 1
So for example, the value 1 in entry (2,3) indicates that the third value of A(:) equals the second unique value of A (namely 2). The 1 in the lower-right entry (5,10) indicates that the tenth value of A(:) is the fifth unique value of A (which is 9).
Now the second output of max is used to extract the row position of the 1 value in each columnn (i.e. to obtain the numbers indicating "second", "fifth" etc in the above example)). These are the desired results. It only remains to reshape them into the shape of A.
Approach 2 (recommended)
The third output of unique does what you want:
[~, ~, labels] = unique(A);
A_new = reshape(labels, size(A));

How to create a symmetric matrix of 1's and 0's with constant row and column sum

I'm trying to find an elegant algorithm for creating an N x N matrix of 1's and 0's, under the restrictions:
each row and each column must sum to Q (to be picked freely)
the diagonal must be 0's
the matrix must be symmetrical.
It is not strictly necessary for the matrix to be random (both random and non-random solutions are interesting, however), so for Q even, simply making each row a circular shift of the vector
[0 1 1 0 ... 0 0 0 ... 0 1 1] (for Q=4)
is a valid solution.
However, how to do this for Q odd? Or how to do it for Q even, but in a random fashion?
For those curious, I'm trying to test some phenomena on abstract networks.
I apologize if this has already been answered before, but none of the questions I could find had the symmetric restriction, which seems to make it much more complicated. I don't have a proof that such a matrix always exists, but I do assume so.
The object that you're trying to construct is known more canonically as an undirected d-regular graph (where d = Q). By the handshaking theorem, N and Q cannot both be odd. If Q is even, then connect vertex v to v + k modulo N for k in {-Q/2, -Q/2 + 1, ..., -1, 1, ..., Q/2 - 1, Q/2}. If Q is odd, then N is even. Construct a (Q - 1)-regular graph as before and then add connections from v to v + N/2 modulo N.
If you want randomness, there's a Markov chain whose limiting distribution is uniform on d-regular graphs. You start with any d-regular graph. Repeatedly pick vertices v, w, x, y at random. Whenever the induced subgraph looks like
v----w
x----y ,
flip it to
v w
| |
x y .
You can perhaps always follow your circular shift algorithm, when possible.
The only condition you need to follow while using the circular shift algorithm is to maintain the symmetric nature in the first row.
i.e. keeping Q 1's in the first row so that Q[0,1] to Q[0,N-1] {Assuming 0 indexed rows and cols, Q[0,0] is 0.} is symmetric, a simple example being 110010011.
Hence, N = 10, Q = 5, you can get many possible arrangements such as:
0 1 0 0 1 1 1 0 0 1
1 0 1 0 0 1 1 1 0 0
0 1 0 1 0 0 1 1 1 0
0 0 1 0 1 0 0 1 1 1
1 0 0 1 0 1 0 0 1 1
1 1 0 0 1 0 1 0 0 1
1 1 1 0 0 1 0 1 0 0
0 1 1 1 0 0 1 0 1 0
0 0 1 1 1 0 0 1 0 1
1 0 0 1 1 1 0 0 1 0
or
0 1 1 0 0 1 0 0 1 1
1 0 1 1 0 0 1 0 0 1
1 1 0 1 1 0 0 1 0 0
0 1 1 0 1 1 0 0 1 0
0 0 1 1 0 1 1 0 0 1
1 0 0 1 1 0 1 1 0 0
0 1 0 0 1 1 0 1 1 0
0 0 1 0 0 1 1 0 1 1
1 0 0 1 0 0 1 1 0 1
1 1 0 0 1 0 0 1 1 0
But as you can see for odd N(that means even N-1) and odd Q there can't be any such symmetric distribution.. Hope it helped.

How can I find a solution of binary matrix equation AX = B?

Given an m*n binary matrix A, m*p binary matrix B, where n > m what is an efficient algorithm to compute X such that AX=B?
For example:
A =
1 1 0 0 1 1 0 1 0 0
1 1 0 0 1 0 1 0 0 1
0 1 1 0 1 0 1 0 1 0
1 1 1 1 1 0 0 1 1 0
0 1 1 0 1 0 1 1 1 0
B =
0 1 0 1 1 0 1 1 0 1 0 0 1 0
0 0 1 0 1 1 0 0 0 1 0 1 0 0
0 1 1 0 0 0 1 1 0 0 1 1 0 0
0 0 1 1 1 1 0 0 0 1 1 0 0 0
1 0 0 1 0 0 1 0 1 0 0 1 1 0
Note, when I say binary matrix I mean matrix defined over the field Z_2, that is, where all arithmetic is mod 2.
If it is of any interest, this is a problem I am facing in generating suitable matrices for a random error correction code.
You can do it with row reduction: Place B to the right of A, and then swap rows (in the whole thing) to get a 1 in row 0, col 0; then xor that row to any other row that has a '1' in column 0, so you have only a single 1 in column 0. Then move to the next column; if [1,1] is zero then swap row 1 with a later row that has a 1 there, then xor rows to make it the only 1 in the column. Assuming 'A' is a square matrix and a solution exists, then you eventually have converted A to unity, and B is replaced with the solution to Ax=B.
If n > m, you have a system with more unknowns than equations, so you can solve for some of the unknowns, and set the others to zero. During the row reduction, if there are no values in a column which have a '1' to use (below the rows already reduced) you can skip that column and make the corresponding unknown zero (you can do this at most n-m times).

Resources