Unable to solve a codechef puzzle? - algorithm

I am trying to solve this apparently beginner level problem. But not even able to come up with a brute force approach.
Here is the problem statement:
Johnny has some difficulty memorizing the small prime numbers. So, his computer science teacher has asked him to play with the following puzzle game frequently.
The puzzle is a 3x3 board consisting of numbers from 1 to 9. The objective of the puzzle is to swap the tiles until the following final state is reached:
1 2 3
4 5 6
7 8 9
At each step, Johnny may swap two adjacent tiles if their sum is a prime number. Two tiles are considered adjacent if they have a common edge.
Help Johnny to find the shortest number of steps needed to reach the goal state.
Input
The first line contains t, the number of test cases (about 50). Then t test cases follow. Each test case consists of a 3x3 table describing a puzzle which Johnny would like to solve.
The input data for successive test cases is separated by a blank line.
Output
For each test case print a single line containing the shortest number of steps needed to solve the corresponding puzzle. If there is no way to reach the final state, print the number -1.
Example
Input:
2
7 3 2
4 1 5
6 8 9
9 8 5
2 4 1
3 7 6
Output:
6
-1

Here is a start on Python for finding the distance to ALL boards that are reachable from the start.
start = '123456789'
needed_moves = {start: 0}
work_queue = [start]
while (len(work_queue)):
board = work_queue.pop(0)
for next_board in next_move(board):
if next_board not in needed_moves:
needed_moves[next_board] = needed_moves[board] + 1
work_queue.append(next_board)
This is a standard pattern for a breadth first search. Just supply a next_move function and some glue for the tests cases and you're good.
For a depth first search, just switch the queue for a stack. Which really means do work_stack.pop() to pop the last element rather than work_queue.pop(0) to get the first one.

Related

Minimum number of steps to sort 3x3 matrix in a specific way

So I started practicing some algorithms and programming before university starts and I ran into this problem:
Given a 3x3 matrix containing the numbers from 0 to 8, find the minimum number of steps required to sort the matrix in the following format:
1 2 3
4 5 6
7 8 0
In one move it is only allowed to pick a cell that is adjacent to the cell which contains the 0 and swap those two cells.
Now, I am really stuck with this one and have no idea how to begin. Any tips and ideas to get me started are appreciated.
This is not homework if anyone thinks that way, I am just trying to exercise and by moving to tougher problems I got stuck. I am not looking for anyone to write the code for me, I just need a point in the right direction because I really want to understand the algorithm behind this. Thank you.
Note: This is actually an AI problem, and not a trivial data structure/algorithm problem.
This problem is called the n-puzzle problem. The example in your question is the 8-puzzle problem.
The way to solve this problem is by trying to shuffle the boxes in a way that each step gets you closer to your final goal. Think of this as a Greedy approach (Best-first search). The best algorithm to use here is the A* algorithm.
We define a state of the game to be the board position, the number of
moves made to reach the board position, and the previous state. First,
insert the initial state (the initial board, 0 moves, and a null
previous state) into a priority queue. Then, delete from the priority
queue the state with the minimum priority, and insert onto the
priority queue all neighboring states (those that can be reached in
one move). Repeat this procedure until the state dequeued is the goal
state. The success of this approach hinges on the choice of priority
function for a state. We consider two priority functions:
Hamming priority function. The number of blocks in the wrong position, plus the number of moves made so far to get to the state. Intutively, a state with a small number of blocks in the wrong position is close to the goal state, and we prefer a state that have been reached using a small number of moves.
Manhattan priority function. The sum of the distances (sum of the vertical and horizontal distance) from the blocks to their goal positions, plus the number of moves made so far to get to the state.
For example, the Hamming and Manhattan priorities of the initial state
below are 5 and 10, respectively.
8 1 3 1 2 3 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
4 2 4 5 6 ---------------------- ----------------------
7 6 5 7 8 1 1 0 0 1 1 0 1 1 2 0 0 2 2 0 3
initial goal Hamming = 5 + 0 Manhattan = 10 + 0
We make a key oberservation: to solve the puzzle from a given state
on the priority queue, the total number of moves we need to make
(including those already made) is at least its priority, using either
the Hamming or Manhattan priority function. (For Hamming priority,
this is true because each block that is out of place must move at
least once to reach its goal position. For Manhattan priority, this is
true because each block must move its Manhattan distance from its goal
position. Note that we do not count the blank tile when computing the
Hamming or Manhattan priorities.)
Consequently, as soon as we dequeue a state, we have not only
discovered a sequence of moves from the initial board to the board
associated with the state, but one that makes the fewest number of
moves.
(Source)

What is a good individual representation for a closed path planning task using genetic algorithm?

There is a n*n grid and in one of the cells of the grid lies an agent A.
A can travel T number of cells.
Each cell in the grid has some weight and the path for A has to maximize that weight.
A also has to return to its starting position within its traveling range T.
What can be a good individual representation to represent the paths?
Methods I have tried:
Chromosome is a list of coordinates.
Chromosome is a list of directions. Each gene is a direction like up, down, up-right, etc. Path never breaks in the middle.
Problems with both methods is that crossing-over almost always generates invalid paths. Paths become broken in the middle. They don't form a closed path. I can't seem to figure out a good way to represent the individual solution and an appropriate crossing-over method. Please help.
First of all, I would say that this problem is a better fit for other approaches, such as maybe ant colony optimization, greedy approaches that give good enough solutions etc. GAs might not work so well for the exact reason you describe.
However, if you must use GAs, here are two possible models that might be worth investigating:
Severely punish invalid paths by giving invalid moves a cost of -infinity. For example, if your chromosome says go from a cell x to an unreachable cell y, consider the cost of y -infinity. This might be worth combining with a low probability of crossover happening, something like 5% maybe.
Don't do crossover, just do some form of more involved mutation of the offspring.
If you want to get even fancier, this is somewhat similar to the travelling salesman problem, which has a lot of research in relation to genetic algorithms:
http://www.lalena.com/AI/Tsp/
http://www.math.hmc.edu/seniorthesis/archives/2001/kbryant/kbryant-2001-thesis.pdf
You could encode the path as a reference list:
Assume these are your locations (1 2 3 4 5 6 7 8 9)
A subset route of (1 2 3 4 8) could be encoded (1 1 2 1 4).
Now take two parents
p1 = (1 1 2 1 | 4 1 3 1 1)
p2 = (5 1 5 5 | 5 3 3 2 1)
which will produce
o1 = (1 1 2 1 5 3 3 2 1)
o2 = (5 1 5 5 4 1 3 1 1)
which will be decoded into these location routes
o1 = 1 – 2 – 4 – 3 – 9 – 7 – 8 – 6 – 5
o2 = 5 – 1 – 7 – 8 – 6 – 2 – 9 – 3 – 4
This way, a crossover will always yield valid results (whether this representation will help you solving your problem better is a different question).
Some additional information can be found here.

Can anyone explain the test case for the puzzle "Repairing Roads"?

I am trying to solve the following puzzle. I am confused by one of the test case.
Here is the problem:
The country of Byteland contains of N cities and N - 1 bidirectional roads between them such that there is a path between any two cities. The roads in Byteland were built long ago and now they are in need of repair. You have been hired to repair all the roads. You intend to do this by dispatching robots on some of the roads. Each robot will repair the road he is currently on and then move to one of the adjacent unrepaired roads. After repairing that, he will move to another adjacent unrepaired road, repair that and so on.
Two roads are adjacent if they have the same city at one of their endpoints. For the process to be efficient, no two robots will can ever repair the same road, and no road can be visited twice. What is the least number of robots needed to accomplish the task?
Input:
The first line contains the number of test cases T. T test cases follow. The first line of each testcase contains N, the number of cities in Byteland. The cities are numbered 0..N - 1. The following N - 1 lines contain the description of the roads. The ith line contains two integers ai and bi, meaning that there is a road connecting cities with numbers ai and bi.
Output:
Output T lines, one corresponding to each test case containing the required answer for that test case.
Constraints:
1 <= T <= 20
1 <= N <= 10000
0 <= ai,bi < N
Now bolow is the test case that I'm confused:
1
15
0 11
1 7
1 11
2 11
2 14
3 4
4 10
4 13
4 8
5 13
6 10
7 9
8 11
11 12
The correct answer is 2, but why?
Note the definition of "adjacent road" here - you're not looking for a traversal where the robot passes each road only once.
Using the definition, you have four "terminal roads" in this graph, 6 10, 5 13, 2 14 and 7 9 - these can't be in the middle of a sequence since they have only one adjacent road. This is a first indication that you can get by with two robots (starting in two of these and ending in the other two). Note then that Byteland is almost split into two subcountries with 4 8 11 the only connecting road, so you can't have two robots passing between the halves, making it natural that one robot will repair each half.
From there, it's fairly trivial to construct a sample traversal (colors - robots, numbers -sequence), of course there are many since you can reverse start/end and shuffle some order in between
All due to Graphviz and my visual cortex, but you weren't asking for the general solution anyway.
It is mentioned in this question that no two robots will ever repair the same road, and no road can be visited twice .
1> if the distance of
the endpoint of one of the branch is greater than one than it is needed to send robot in that direction .
2> distance of endpoint from any vertex =1 then not require any extra robot
https://i.stack.imgur.com/o7zm6.png

Generate multiple sequences of numbers with unique values at each index

I have a row with numbers 1:n. I'm looking to add a second row also with the numbers 1:n but these should be in a random order while satisfying the following:
No positions have the same number in both rows
No combination of numbers occurs twice
For example, in the following
Row 1: 1 2 3 4 5 6 7 ...
Row 2: 3 6 15 8 13 12 7 ...
the number 7 occurs at the same position in both rows 1 and 2 (namely position 7; thereby not satisfying rule 1)
while in the following
Row 1: 1 2 3 4 5 6 7 ...
Row 2: 3 7 15 8 13 12 2 ...
the combination of 2+7 appears twice (in positions 2 and 7; thereby not satisfying rule 2).
It would perhaps be possible – but unnecessarily time-consuming – to do this by hand (at least up until a reasonable number), but there must be quite an elegant solution for this in MATLAB.
This problem is called a derangment of a permutation.
Use the function randperm, in order to find a random permutation of your data.
x = [1 2 3 4 5 6 7];
y = randperm(x);
Then, you can check that the sequence is legal. If not, do it again and again..
You have a probability of about 0.3 each time to succeed, which means that you need roughly 10/3 times to try until you find it.
Therefore you will find the answer really quickly.
Alternatively, you can use this algorithm to create a random derangment.
Edit
If you want to have only cycles of size > 2, this is a generalization of the problem.
In it is written that the probability
in that case is smaller, but big enough to find it in a fixed amount of steps. So the same approach is still valid.
This is fairly straightforward. Create a random permutation of the nodes, but interpret the list as follows: Interpret it as a random walk around the nodes, and if node 'b' appears after node 'a', it means that node 'b' appears below node 'a' in the lists:
So if your initial random permutation is
3 2 5 1 4
Then the walk in this case is 3 -> 2 -> 5 -> 1 -> 4 and you creates the rows as follows:
Row 1: 1 2 3 4 5
Row 2: 4 5 2 3 1
This random walk will satisfy both conditions.
But do you wish to allow more than one cycle in your network? I know you don't want two people to have each other's hat. But what about 7 people, where 3 of them have each other's hats and the other 4 have each other's hats? Is this acceptable and/or desirable?
Andrey has already pointed you to randperm and the rejection-sampling-like approach. After generating a permutation p, an easy way to check whether it has fixed point is any(p==1:n). An easy way to check whether it contains cycles of length 2 is any(p(p)==1:n).
So this gets permutations p of 1:n fulfilling your requirements:
p=[];
while (isempty(p))
p=randperm(n);
if any(p==1:n), p=[];
elseif any(p(p)==1:n), p=[];
end
end
Surrounding this with a for loop and for each counting the iterations of the while loop, it seems that one needs to generate on average 4.5 permutations for every "valid" one (and 6.2 if cycles of length three are not allowed, either). Very interesting.

Finding good heuristic for A* search

I'm trying to find the optimal solution for a little puzzle game called Twiddle (an applet with the game can be found here). The game has a 3x3 matrix with the number from 1 to 9. The goal is to bring the numbers in the correct order using the minimum amount of moves. In each move you can rotate a 2x2 square either clockwise or counterclockwise.
I.e. if you have this state
6 3 9
8 7 5
1 2 4
and you rotate the upper left 2x2 square clockwise you get
8 6 9
7 3 5
1 2 4
I'm using a A* search to find the optimal solution. My f() is simply the number of rotations needed. My heuristic function already leads to the optimal solution (if I modify it, see the notice a t the end) but I don't think it's the best one you can find. My current heuristic takes each corner, looks at the number at the corner and calculates the manhatten distance to the position this number will have in the solved state (which gives me the number of rotation needed to bring the number to this postion) and sums all these values. I.e. You take the above example:
6 3 9
8 7 5
1 2 4
and this end state
1 2 3
4 5 6
7 8 9
then the heuristic does the following
6 is currently at index 0 and should by at index 5: 3 rotations needed
9 is currently at index 2 and should by at index 8: 2 rotations needed
1 is currently at index 6 and should by at index 0: 2 rotations needed
4 is currently at index 8 and should by at index 3: 3 rotations needed
h = 3 + 2 + 2 + 3 = 10
Additionally, if h is 0, but the state is not completely ordered, than h = 1.
But there is the problem, that you rotate 4 elements at once. So there a rare cases where you can do two (ore more) of theses estimated rotations in one move. This means theses heuristic overestimates the distance to the solution.
My current workaround is, to simply excluded one of the corners from the calculation which solves this problem at least for my test-cases. I've done no research if really solves the problem or if this heuristic still overestimates in some edge-cases.
So my question is: What is the best heuristic you can come up with?
(Disclaimer: This is for a university project, so this is a bit of homework. But I'm free to use any resource if can come up with, so it's okay to ask you guys. Also I will credit Stackoverflow for helping me ;) )
Simplicity is often most effective. Consider the nine digits (in the rows-first order) as forming a single integer. The solution is represented by the smallest possible integer i(g) = 123456789. Hence I suggest the following heuristic h(s) = i(s) - i(g). For your example, h(s) = 639875124 - 123456789.
You can get an admissible (i.e., not overestimating) heuristic from your approach by taking all numbers into account, and dividing by 4 and rounding up to the next integer.
To improve the heuristic, you could look at pairs of numbers. If e.g. in the top left the numbers 1 and 2 are swapped, you need at least 3 rotations to fix them both up, which is a better value than 1+1 from considering them separately. In the end, you still need to divide by 4. You can pair up numbers arbitrarily, or even try all pairs and find the best division into pairs.
All elements should be taken into account when calculating distance, not just corner elements. Imagine that all corner elements 1, 3, 7, 9 are at their home, but all other are not.
It could be argued that those elements that are neighbors in the final state should tend to become closer during each step, so neighboring distance can also be part of heuristic, but probably with weaker influence than distance of elements to their final state.

Resources