Laser Grid Puzzle - algorithm

Saw the following puzzle on HN and thought I would repost here. It can be solved using Simplex, but I was wondering if there is a more elegant solution, or if someone can prove NP-completeness.
Each dot below represents the position of a laser. Indicate the direction that the laser should fire by replacing the dot with ^, v, <, or >. Each grid position i,j should be hit by exactly grid[i][j] lasers. In the example below, grid position 0,0 should be hit by exactly grid[0][0] = 2 lasers.
A laser goes through everything in its path including other guns (without destroying those guns).
2 2 3 . 1 . 2 2 3
1 . 2 1 1 . 1 . 2
2 3 . 1 . 2 . 4 .
. 3 . 2 2 . 2 3 4
1 . 2 . 2 3 2 . .
2 3 . 3 . 3 2 2 .
3 . 2 4 2 . 2 . 2
1 1 . . 1 3 . 2 .
. 2 1 . 2 . 1 . 3

If it can be solved with Simplex (Linear Programming) it isn't NP-complete.

Related

pathfinding with multiple source and sinks?

I have a shortest path problem that I need to solve, and I'm fairly certain that there should be a efficient solution
I have this fun representation of a graph:
as ascii:
input
. N N N N N N
W 7 9 8 8 7 5 N . . . N N N
W 2 2 2 1 1 6 6 N N N 5 5 N E
W 1 2 3 2 2 2 2 4 5 5 4 2 5 E
. S S S 3 3 3 2 6 5 4 2 2 2 E
. . . . S S 2 2 2 2 3 7 2 2 E
. . . . . . S 2 3 2 7 7 7 7 E
. . . . . . . S 7 7 7 7 7 7 E
. . . . . . . S 7 7 7 S S 7 E
. . . . . . . . S 7 S . . S
. . . . . . . . . S
Output:
35
I need to find the shortest a path from one of the 'E' spots to one of the 'W' spots, walking over the numbered spots. We are not able to walk on the 'N' and 's' spots. When we stand at a spot, we´re able to walk up, down,left and right. I need to find the shortest path in terms of the numbered squares that I am walking on. Here is a more simple example:
I would create a double directed DAG with all edges going towards a numbered edge, having that number as weight, and all edges going to E or W having weight 0:
my attempt
Now this is a case of finding a shortest path from multiple sources to muliple sinks.
My naive thought is that I could run Dijkstra from every w, to every E. This would however run in something like O(W*dijkstra^E) (where E is the amount of E nodes)
Is there any smarter way to do a multi-source multi-sink dijsktra?
After giving this some thought, and I think I have come up with a solution myself. The accepted answer is completely valid and good, but I think should run faster than A bfs that in the worst case needs to evaluate each edge E times.
Here goes:
I connect all E nodes with a source, with edges going from the source (s) to E, with weight 0.
All W nodes are also connected to a sink (t), edges going from W to sink.
This means that the beforeshown graph will look like this:
Now I should be able just to run a regular ol' dijkstra from s to t
A solution was mentioned in the comments but bears conversion to an answer: run a normal BFS but re-enqueue any previously visited nodes which can be reached with lower cost than previously thought. Re-enqueing a newly-discovered cheaper path to a visited node lets us recompute its neighbor paths as well.
The downside is that BFS will explore all nodes at least once, so the optimality depends on the type of graph you have--if it's a graph with many starting and ending points relative to the size of the graph as in your example, this is good, whereas running multiple Dijkstra's becomes appealing as the number of sources and sinks diminishes relative to the size of the graph.
Here's the code:
const findAllCoords = (G, tgt) =>
G.reduce((a, row, ri) => {
const res = row.reduce((a, cell, ci) =>
cell === tgt ? [...a, [ci, ri]] : a
, []);
return res.length ? [...a, ...res] : a;
}, [])
;
const shortestPathMultiSrcMultiDst = (G, src, dst) => {
const key = ([x, y]) => `${x} ${y}`;
const dstCoords = findAllCoords(G, dst);
const visited = Object.fromEntries(
dstCoords.map(e => [key(e), Infinity])
);
const neighbors = ([x, y]) =>
[[0, -1], [-1, 0], [1, 0], [0, 1]]
.map(([xx, yy]) => [x + xx, y + yy])
.filter(([x, y]) =>
G[y] && (!isNaN(G[y][x]) || G[y][x] === dst)
)
;
const q = findAllCoords(G, src).map(e => [e, 0]);
while (q.length) {
let [xy, cost] = q.shift();
const [x, y] = xy;
const k = key(xy);
cost += isNaN(G[y][x]) ? 0 : +G[y][x];
if (!(k in visited) || cost < visited[k]) {
visited[k] = cost;
q.push(...neighbors(xy).map(e => [e, cost]));
}
}
return Math.min(...dstCoords.map(e => visited[key(e)]));
};
const G = `
. N N N N N N
W 7 9 8 8 7 5 N . . . N N N
W 2 2 2 1 1 6 6 N N N 5 5 N E
W 1 2 3 2 2 2 2 4 5 5 4 2 5 E
. S S S 3 3 3 2 6 5 4 2 2 2 E
. . . . S S 2 2 2 2 3 7 2 2 E
. . . . . . S 2 3 2 7 7 7 7 E
. . . . . . . S 7 7 7 7 7 7 E
. . . . . . . S 7 7 7 S S 7 E
. . . . . . . . S 7 S . . S
. . . . . . . . . S
`.trim().split("\n").map(e => e.split(" "))
;
console.log(shortestPathMultiSrcMultiDst(G, "W", "E"));
OP shared a better answer that simply turns the problem into a regular Dijkstra-solvable graph by connecting all sources to a node and all sinks to a node, rendering this solution pretty much pointless as far as I can tell.

Constrained N-Rook Number of Solutions

The purpose of this post is mainly for keywords for related researches.
Unconstrained N-Rook Problem
Count all possible arrangements of N rooks on an N by M (N<=M) chessboard so that no rooks are attacking each other.
The solution is trivial: C(M,N)N!
Constrained N-Rook Problem
You cannot put a rook at certain places of the chessboard.
For example, if the chessboard is presented as a 0-1 matrix, where 0 are the places you cannot put a rook at. So the solution for the matrix
1 1 1
1 1 1
0 1 1
is 4:
R . . | R . . | . R . | . . R
. R . | . . R | R . . | R . .
. . R | . R . | . . R | . R .
Related Problem
A backtracking algorithm can be easily modified from N-Queen problem. However, now I want to solve a problem for around N=28. This solution is too huge to count 1 by 1, even wiki said
The 27×27 board is the highest-order board that has been completely enumerated.
Chances to Speed Up
There are a few chances I thought of so far to speed up the algorithm.
=====Factorial for Unconstrained Submatrix=====
This is a Divide and Conquer method. e.g. The matrix above
1 1 1
1 1 1
0 1 1
can be divided as
A B
1 1 1 | 0 1 1
1 1 1 |
and the solution is equal to sol(A)*sol(B), where sol(A)=2! which can be calculated at once (factorial is much faster than backtracking).
=============Rearrangement=============
Sometimes rearrangement can help to divide the subproblem. e.g. The matrix
1 1 1
1 0 1
1 1 1
is equivalent to
1 1 1
1 1 1
0 1 1
Question
What is the keyword for this kind of problem?
Are there any efficient developed technique for this kind of problem?
The rook polynomial, rook coefficient, restricted permutations and permanent are the keywords.
From Theorem 3.1 of Algorithm for Finding the Coefficients of Rook Polynomials
The number of arrangements of n objects with restriction board B is equal to permanent of B.
Here B is what we defined in the question, a 0-1 matrix where 1 is ok, 0 is restricted for a rook.
So now we need to efficiently calculate the permanent of a matrix.
Fortunately, from this code golf, Ton Hospel uses Glynn formula with a Gray code and Ryser formula, and reach about 57 seconds on the tester's system for n=36, which is quite enough for the questioner's case.

Combining add cases and add variables by merging files in SPSS

I would like to merge different SPSS files. The PAID indicates different persons. The files also contain the variable ID which indicates the moment of measurement. So ID=1 means that the data are results of measurement one (ID=2 ; measurement two etc.). However, not all data files contain the same moments of measurement.
I have already read the following post, but that has not completely answered my question:
SPSS - merging files with duplicate cases of ID variable and new cases/variables
Example data files
Data file 1:
PAID ID X1 X2 X3 X4
1 1 3 4 4 5
2 1 3 4 5 6
3 1 3 4 4 6
4 1 . . . .
Data file 2:
PAID ID X5 X6 X7
1 1 1 1 2
1 2 1 2 1
2 1 1 2 2
2 2 2 2 2
3 1 1 1 1
3 2 1 . .
4 1 1 1 1
4 2 2 2 2
I want the following result:
PAID ID X1 X2 X3 X4 X5 X6 X7
1 1 3 4 4 5 1 1 2
1 2 . . . . 1 2 1
2 1 3 4 5 6 1 2 2
2 2 . . . . 2 2 2
3 1 3 4 4 6 1 1 1
3 2 . . . . 1 . .
4 1 . . . . 1 1 1
4 2 . . . . 2 2 2
I think I have to use some combination of the functions add cases and add variables. However, is this possible within SPSS? And if so, how can I do this?
Thanks in advance!
This will do the job:
match files /file='path\DataFile1.sav' /file='path\DataFile2.sav'/by paid id.
Please note though, both files need to be sorted by paid id before running the match.
To demonstrate with your sample data:
*first preparing demonstration data.
DATA LIST list/paid id x1 to x4 (6f).
begin data.
1,1,3,4,4,5
2,1,3,4,5,6
3,1,3,4,4,6
4,1, , , ,
end data.
* instead of creating the data, you can can get your original data:
* get file="path\file name 1.sav".
sort cases by paid id.
dataset name DataFile1.
DATA LIST list/paid id x5 to x7 (5f).
begin data.
1,1,1,1,2
1,2,1,2,1
2,1,1,2,2
2,2,2,2,2
3,1,1,1,1
3,2,1, ,
4,1,1,1,1
4,2,2,2,2
end data.
sort cases by paid id.
dataset name DataFile2.
match files /file=DataFile1 /file=DataFile2/by paid id.
exe.
the result looks like this:
paid id x1 x2 x3 x4 x5 x6 x7
1 1 3 4 4 5 1 1 2
1 2 1 2 1
2 1 3 4 5 6 1 2 2
2 2 2 2 2
3 1 3 4 4 6 1 1 1
3 2 1
4 1 1 1 1
4 2 2 2 2

Pattern of decoding instruction

I am analyzing Agner Fog's
"Optimizing subroutines in assembly language: An optimization guide for x86 platforms".
Especially I am trying to understand chapter 12.7. And there is an issue I can not understand. The author writes:
Instruction decoding in the PM processor follows the 4-1-1 pattern. The pattern of (fused)
μops for each instruction in the loop in example 12.6b is 2-2-2-2-2-1-1-1. This is not optimal,
and it will take 6 clock cycles to decode. This is more than the retirement time, so we can
conclude that instruction decoding is the bottleneck in example 12.6b. The total execution
time is 6 clock cycles per iteration or 3 clock cycles per calculated Y[i] value.
What does it mean that instruction decoding follows the 4-1-1 pattern and how to know it?
Pattern for loop is 2-2-2-2-2-1-1-1. Ok, but why it takes 6 cycle to decode I don't know. Why?
The CPU's frontend can decode multiple (macro) instructions in one clock cycle. Each macro instruction decodes to 1 or more micro-ops (μops). What the 4-1-1 pattern means is that the first parallel decoder can handle a complex instruction that decodes to up to 4 μops. But the second and third parallel decoders can only handle instructions that decode to 1 μop each (if not satisfied, they don't consume the instruction).
The 5 instructions that decode to 2 μops will must be consumed by the first decoder, then the tail allows some parallelism.
2 2 2 2 2 1 1 1 (Macro-instruction stream, μops per instruction)
^ x x
4 1 1 (Decode cycle 0)
. 2 2 2 2 1 1 1
^ x x
4 1 1 (Decode cycle 1)
. . 2 2 2 1 1 1
^ x x
4 1 1 (Decode cycle 2)
. . . 2 2 1 1 1
^ x x
4 1 1 (Decode cycle 3)
. . . . 2 1 1 1
^ ^ ^
4 1 1 (Decode cycle 4)
. . . . . . . 1
^ x x
4 1 1 (Decode cycle 5)
. . . . . . . . (Instruction stream fully consumed)

Maze solving optimal no left turn algorithm

I am working on a project where I need to solve a maze using the minimum number of right turns and no left turns.
The distance travelled is irrelevant as long as right turns are minimized. We are asked to implement our program using both a backtracking algorithm and an optimal (time) one.
For the backtracking algorithm I was going use a stack. My algorithm would be something like:
Push all four possible starting directions on the stack.
Follow a path, going straight whenever possible.
If we reach the end of the maze return the current path length as the best.
If we reach a dead end backtrack to the last possible right turn and take it.
If the current path length is greater than the current best, backtrack to the last possible right turn and take it.
I was wondering if anyone could point me in the direction of an optimal algorithm for this.
I'm having a tough time thinking of anything better than the backtracking one.
I think you can do it by first finding all the points that are reachable with 0 right turns. Then with just 1 right turn, and so on. You can use a queue for doing that. Note that in the n-th phase you've got optimal solutions for all the points that can be reached with n right turns. More so - any not yet reached point is reachable with > n points or not reachable at all. In order to achieve optimal time complexity you have to use the fact that you need to search for new reachable points only from those reached points, which have an unreached neighbour in the appropriate direction. As every point has only 4 neighbours you will only search from it 4 times. You can implement it by maintaining a separate list for every direction D containing all the reached points with an unreached neighbour in that direction. This gives you a time complexity proportional to the area of the maze that is proportional to the size of your input data.
Below I present a graphical example:
. . . . . . (0) . . . . . 0 1 1 1 1 (1) 0 1 1 1 1 1
. ####### . . 0 ########## . 0 ########## . 0 ########## 2
. # . # . . 0 # . # . . 0 # . # . . 0 # . # . (2)
. # . . . . 0 # . . . . 0 # . . . . 0 # . . . (2)
. #### . # . 0 #### . # . 0 #### . # . 0 #### . # 2
(.) . . . . . (0) . . . . . 0 1 1 1 1 1 0 1 1 1 1 1
0 1 1 1 1 1 0 1 1 1 1 1
0 ########## 2 0 ########## 2
0 # . # 3 2 0 # 4 # 3 2
0 # (3) 3 3 2 0 # 3 3 3 2
0 #### . # 2 0 #### 4 # 2
0 1 1 (1) 1 1 0 1 1 1 1 1
( ) denote reached points with the appropriate neighbour unreached
Build a graph by constructing four nodes for every position in the maze. Every node will correspond to a particular direction: N, S, E, W.
There will be edges between every node and at most three of its adjacent neighbors: the ones to the "front", "back" and "right" (if they exist). The edge leading to the node in the "front" and "back" will have weight 0 (since the path length doesn't matter), whereas the edge to the node in the "right" will have weight 1 (this is what represents the cost of making a right turn).
Once the graph is set up (and probably the best way to do this is to reuse the original representation of the maze) a modified variant of the breadth-first search algorithm will solve the problem.
The trick to handle the 0/1 edge weights is to use a deque instead of the standard queue implementation. Specifically, nodes reached through 0 weight edges will be pushed in the front of the deque and the ones reached through edges of weight 1 will be pushed in the back.

Resources