Two robots on a line - algorithm

You probably know the problem with the two robots dropped on a line when you need to program them to meet.
Two robots are dropped from an airplane and land on a single line (with discrete positions) using a parachute which is left at the landing point. The robots are both facing north, they are an unknown distance apart, and one has landed directly east of the other.
The robots are now to be programmed such that they meet each other. They can be instructed to move left or right to a neighboring position and to check whether a parachute is present at the current location. If the other robot is met both robots stop there and live happily ever after.
The parachute check might conditionally execute any number of instructions and any block of instructions may be repeated unconditionally. Write down a program that both robots can follow simultaneously and which garuantees that they meet.
You have to create a generic algorithm (a little pleonastic) that applied to both robots guarantees that the robots will meet. They leave their parachute on the spot where they are dropped and they can check if in the current position there is a parachute.
The original statement is here: http://en.wikibooks.org/wiki/Puzzles/Logic_puzzles/Parachuted_Robots
There is also a solution that I don't understand. If someone can make any sense of it, please help me with a little explaning. Any other solution would be much appreciated.
My first thought on this problem would be to program the robot to choose randomly to first go right or left, and then make something like an exponential search: first go 2 positions to right, then 4 to left etc. If in one of this "trips" in right or left the robot finds the second parachute (the one that was used by the other robot), the robot will only search in that direction. Does this make any sense?
Thank you very much!

My program is actually shorter, and works like a charm too:
start: left
skipNext
goto start
next: left
goto next
This works because the second loop is faster than the first loop.
You can test your program here: http://david-peter.de/parachuting-robots/

Your "first thought" solution should work too, but it will take a while longer for the robots to meet than the solution you cited at wikibooks. To recap, the wikibooks solution is:
10 Go right
20 Go left
30 Go right
40 If Not Parachute GOTO 10
50 Go right
60 GOTO 50
In case you don't recognize the syntax, the author is trying to mimic BASIC, where the numbers 10-60 are line numbers, and the GOTOs are code jumps.
Lines 10-40 have both robots moving slowly right. The "right, left, right" steps slow down movement to the right. It could have just as easily been "right, wait". Line 40 checks for the parachute. When both robots landed on the line, exactly one of them was to the left of the other. The left robot will eventually find the other parachute. The right never will. When the left robot finds the right robot's parachute, it enters lines 50-60, where it moves right without the slowdown. Now that the left robot is moving right faster than the right robot, the left will eventually catch up.
Personally I think the algorithm you posed is more fun, since both robots would swing back and forth a lot. In a way it's a similar algorithm, but the slowdown grows linearly with each step.

It seems to me that your algorithm ought to work. The idea in the posted solution is that both robots keep a pattern of going right left right, meaning they are advancing right at a certain pace. But when the robot on the left finds the other's parachute, it starts moving to the right at a faster pace since it does not step once to the left as part of its walking pattern but keeps going right, eventually catching up to the robot on the right.

Both robots move left till the right robot finds the left robot's parachute and starts sprinting towards the left robot. Then they collide.
start: left
skipNext
goto start
goto moveLeftFast
moveLeftFast: left
goto moveLeftFast

I made this:
start: left
skipNext
goto start
fastL: left
left
goto fastL
The idea is simple: we go left one bit. One of the robots (the one on the right) will eventually bump into parachute and then it will skip out of the fist loop, and enter the second which makes him go left twice as fast.

Related

How to map out a maze as a robot?

First - I've looked through similar looking questions but they did not solve my problem, this is no repetition (I hope).
I'm building and programming a robot with an Arduino Nano that is supposed to solve a maze. It gets put somewhere in the maze and then has to find an item. The next time it is supposed to go straight to the item (it does not have to be the shortest way but no dead ends allowed).
It is not necessary to know the whole maze because as long as he has one way to the item it is good. As I said, I don't need the shortest way.
The maze is 2D, I just put black tape on a white table and the robot is supposed to use a line sensor to follow the lines.
There are no other sensors to orientate himself. First I thought of making an 2D array and each field of the maze a field in there. But since it's just a normal line sensor the robot doesn't know if a straight line is one or two fields long and the whole thing does not work.
I also tried DFS or something like that but a similar problem here. The maze is circular and how is the robot supposed to know the Node was already found before and it is the same?
It would be nice if anyone had an idea!
Although orientation is a little bit fuzzy it is possible by using the decisions. A decision has to be reproducable. It could be represented by a class:
public class Decision {
boolean[] directions = new boolean[2]; // 0 = left, 1 = straight, 2 = right
// at least 2 of them should be true or it is no decision
int path; // 0-2 to mark the current path
}
Create a stack of decisions.
If there is only one possible direction at the beginning (back doesn't count and is treated later), then move forward until you meet the first decision.
Push the decision with all possible directions on the stack.
Set path to the first possible direction and move that way.
If you end up with another decision: continue at 3.
If you find the token: abort, you found a reproducible way without dead-ends.
If it is a dead-end: return to the previous decision node (the first one one the way back) and continue with 6.
Pop the decision and try the next possible direction (set the new path and push the decision) and continue at 5.
Unless you have tried all directions, then move back another decision and continue with 6.
If there are no more decisions (the special case mentioned above, we went in the wrong direction at the beginning): move forward until you meet the first decision and continue at 3. This means you need another boolean variable to indicate if you should go backwards right at the beginning.
You have to be careful when coming back from left and want to try straight next you would have to turn left and don't go straight. So there is a little calculation involved.
The algorithm has a problem for loop shaped decisions if you start the wrong way at the beginning. I think this could be escaped by setting an upper boundary, e.g. if you still haven't found the token and met 30 decision nodes (going forward), then you are probably running in circles, so go back to start and now instead of trying the directions in increasing order, try them in decreasing order.

Dots and boxes, even chains for 1st player, suggest move

I got to know that on a board of 3x3 box, player 1 should try to make even number of long chains. (long chain is a chain of length 3 or more). source
To summarize: (credit)
I need an even number of chains
I am player one, as an even number of moves has been made, and there are an even number of dots.
(This is known as the chain rule, and anyone who is unfamiliar with it should learn it as it is a key to winning dots and boxes. The number of squares already in chains means the winner of the chains battle in this game wins the majority of the squares by sacrificing two at the end of each of the chains they are given.)
I have been trying to play the game on this site but have been unable to win so far.
Attaching the board configuration when I got an even number of chains and its my turn to move.
What should be my move?
Can you give a winning strategy against the bot on this site?
What am I missing here? It seems to me that even though I got even number of long chains, no matter what move I make I will end up losing.
I didn't follow the YouTube link (readable text preferred) and don't know about the long chains. E.g., shouldn't we treat cycles differently from paths?
Still, in the given position, you can move anywhere on the right, giving the three right squares to your opponent and then taking the remaining six squares after his move.

Lights out game algorithm

It's a homework. I have to design and lights out game using backtracking description is below.
The game consists of a 5-by-5 grid of lights; when the game starts, a set of these lights (random, or one of a set of stored puzzle patterns) are switched on. Pressing one of the lights will toggle it, and the four lights adjacent to it, on and off. (Diagonal neighbours are not affected.) The game provides a puzzle: given some initial configuration where some lights are on and some are off, the goal is to switch all the lights off, preferably in
as few button presses as possible.
My approach is go from 1 to 25 and check if all the lights are off or not. If not then I will check for 1 to 24 and so on until I reach 1 or found solution. No if there is no solution then I will start from 2 to 24 and follow the above process till I reach 2 or found solution.
But through this I am not getting the result ? for example light at (0,0) (1,1) (2,2) (3,3) (4,4) are ON?
If any one need code I can post it.
Can any one tell me correct approach using backtracking to solve this game ?
Thanks.
There is a standard algorithm for solving this problem that is based on Gaussian elimination over GF(2). The idea is to set up a matrix representing the button presses a column vector representing the lights and then to use standard matrix simplification techniques to determine which buttons to press. It runs in polynomial time and does not require any backtracking.
I have an implementation of this algorithm that includes a mathematical description of how it works available on my personal site. I hope you find it useful!
Edit: If you are forced to use backtracking, you can use the following facts to do so:
Any solution will never push the same button twice, since doing so would cancel out a previous move.
Any solution either pushes the first button or does not.
Given this approach, you could solve this using backtracking using a simple recursive algorithm that keeps track of the current state of the board and which buttons you've already made decisions about:
If you've decided about each button, then return whether the board is solved or not.
Otherwise:
Try pushing the next button and seeing if the board is recursively solvable from there.
If so, return success.
Otherwise, try not pushing the next button and seeing if the board is recursively solvable from there.
If so, return success. If not, return failure.
This will explore a search space of size 225, which is about 32 million. That's big, but not insurmountably big.
Hope this helps!
Backtracking means:
Incrementally build a solution, throwing away impossible solutions.
Here is one approach using the fact that there is locality of inputs and outputs (pressing a button affects square around it).
problem = GIVEN
solutions = [[0],[1]] // array of binary matrix answers (two entries, a zero and a one)
for (problemSize = 1; problemSize <= 5; problemSize++) {
newSolutions = [];
foreach (solutions as oldSolution) {
candidateSolutions = arrayOfNByNMatriciesWithMatrixAtTopLeft(min(5,problemSize+1), oldSolution);
// size of candidateSolutions is 2^((problemSize+1)^2 - problemSize^2)
// except last round candidateSolutions == solutions
foreach (candidateSolutions as candidateSolution) {
candidateProblem = boardFromPressingButtonsInSolution(candidateSolution);
if (compareMatrix(problem, candidateProblem, 0, 0, problemSize, problemSize)==0)
newSolutions[] = candidateSolution;
}
}
solutions = newSolutions;
}
return solutions;
As already suggested, you should first form a set of simultaneous equations.
First thing to note is that a particular light button shall be pressed at most once because it does not make sense to toggle the set of lights twice.
Let Aij = Light ij Toggled { Aij = 0 or 1 }
There shall be 25 such variables.
Now for each of the lights, you can form an equation looking like
summation (Amn) = 0. { Amn = 5 light buttons that toggle the light mn }
So you will have 25 variables and 25 unknowns. You can solve these equations simultaneously.
If you need to solve it using backtracking or recursion you can solve the equations that way. Just assume an initial value of variables, see if they satisfy all the equations. If not, then back track.
The Naive Solution
First, you're going to need a way to represent the state of the board and a stack to store all of the states. At each step, make a copy of the board, changed to the new state. Compare that state to all states of the board you've encountered so far. If you haven't seen it, push that state on top of the stack and move on to the next move. If you have seen it, try the next move. Each level will have to try all possible 64 moves before popping the state from the stack (backtracking). You will want to use recursion to manage the state of the next move to check.
There are at most 264 possible board configurations, meaning you could potentially go on a very long chain of unique states and still run out of memory. (For reference, 1 GB is 230 bytes and you need a minimum of 8 bytes to store the board configuration) This algorithm is not likely to terminate in the lifetime of the known universe.
You need to do something clever to reduce your search space...
Greedy-First Search
You can do better by searching the states that are closest to the solved configuration first. At each step, sort the possible moves in order from most lights off to least lights off. Iterate in that order. This should work reasonably well but is not guaranteed to get the optimal solution.
Not All Lights-Out Puzzles Are Solvable
No matter what algorithm you use, there may not be a solution, meaning you might search forever (or several trillion years, at least) without finding a solution.
You will want to check the board for solvability (which is a much faster algorithm as it turns out) before wasting any time trying to find a solution.

Is there a way to avoid unnecessary recursion?

I posted this question over at CodeReview, but I came to realize that it's not so much a Haskell question as it is an algorithm question.
The Haskell code can be found on my github repo but I think the code isn't as important as the general concept.
Basically the program figures out the optimal first set of moves in a game of Kalaha (the Swedish variation). Only the first "turn" is considered, so we assume that you get to start and that anything from the point of the opponent getting to move is not computed.
Kalaha board http://www.graf-web.at/mwm/kalaha.jpg
The board starts off with empty stores and a equal amount of marbles in each pot.
You start your turn by choosing a non-empty pot on your side, pick all of the marbles up from that pot and then move around the board by dropping one marble when passing a pot. If your last marble lands in the store, you get another turn. If you land in a non-empty, non-store pot, you pick up all of the contents of that pot and continue. Finally, if you land in an empty pot, the turn is passed to the opponent.
So far I've solved this by picking all possible paths and then sorting them according to the amount of marbles in the store by the end. A path would mean to start from one of your pots, do all the necessary pick-up-and-move-around and see if you either land in a store or in an empty pot. If you land in the store you get to continue, and now there are as many new branches as there are non-empty pots on your side.
The problem lies in the fact that if you start with five marbles in the pots, it's already quite a few paths. Jump up to six and ghci runs out of memory.
The reason I can't figure out how to make this less expensive is because I think that each path is necessary during computation. While I'll only need at most three paths (the best ones) out of the thousands (or millions) generated, the rest need to be run through to see if they're actually better than the previous ones.
If one is longer (generally better) then that's good but costly. If it's shorter than any previous path, then program still had to compute that path to find that out.
Is there any way around this, or is computing all the paths necessary by definition?
Just try them all out in order, recording your sequences of moves as sequences of numbers 1 through 6 (representing the pot that you pick the marbles from), each time replaying the whole sequence from the start. Keep and update just the three winners, plus the very last sequence of moves so you'd know what to try next. If there's no next legal moves, go back one notch.
It's going to be prohibitively slow perhaps, but will use very little memory. You don't store resulting positions, only numbers of pots picked from, and replay the sequence anew each time from the starting position, altering the very last move (instead of 2, next try 3, 4 etc.; if no more legal moves, backtrack one level). Or maybe store positions just for the very last sequence of moves tried, for easier backtracking.
It's a typical space for speed trade-of then.
You could try parallellizing using this parallel version of map:
parMap :: (a -> b) -> [a] -> Eval [b]
parMap f xs = map f xs `using` parList rseq
Then you will spark off a new thread for each choise in your branch.
if you use as parMap pathFunction kalahaPots as your recursion, it will spark a lot of threads, but it might be faster, you could chunk it but i'm not that good of a parallell haskeller.

Mahjong - Arrange tiles to ensure at least one path to victory, regardless of layout

Regardless of the layout being used for the tiles, is there any good way to divvy out the tiles so that you can guarantee the user that, at the beginning of the game, there exists at least one path to completing the puzzle and winning the game?
Obviously, depending on the user's moves, they can cut themselves off from winning. I just want to be able to always tell the user that the puzzle is winnable if they play well.
If you randomly place tiles at the beginning of the game, it's possible that the user could make a few moves and not be able to do any more. The knowledge that a puzzle is at least solvable should make it more fun to play.
Place all the tiles in reverse (ie layout out the board starting in the middle, working out)
To tease the player further, you could do it visibly but at very high speed.
Play the game in reverse.
Randomly lay out pieces pair by pair, in places where you could slide them into the heap. You'll need a way to know where you're allowed to place pieces in order to end up with a heap that matches some preset pattern, but you'd need that anyway.
I know this is an old question, but I came across this when solving the problem myself. None of the answers here are quite perfect, and several of them have complicated caveats or will break on pathological layouts. Here is my solution:
Solve the board (forward, not backward) with unmarked tiles. Remove two free tiles at a time. Push each pair you remove onto a "matched pair" stack. Often, this is all you need to do.
If you run into a dead end (numFreeTiles == 1), just reset your generator :) I have found I usually don't hit dead ends, and have so far have a max retry count of 3 for the 10-or-so layouts I have tried. Once I hit 8 retries, I give up and just randomly assign the rest of the tiles. This allows me to use the same generator for both setting up the board, and the shuffle feature, even if the player screwed up and made a 100% unsolvable state.
Another solution when you hit a dead end is to back out (pop off the stack, replacing tiles on the board) until you can take a different path. Take a different path by making sure you match pairs that will remove the original blocking tile.
Unfortunately, depending on the board, this may loop forever. If you end up removing a pair that resembles a "no outlet" road, where all subsequent "roads" are a dead end, and there are multiple dead ends, your algorithm will never complete. I don't know if it is possible to design a board where this would be the case, but if so, there is still a solution.
To solve that bigger problem, treat each possible board state as a node in a DAG, with each selected pair being an edge on that graph. Do a random traversal, until you find a leaf node at depth 72. Keep track of your traversal history so that you never repeat a descent.
Since dead ends are more rare than first-try solutions in the layouts I have used, what immediately comes to mind is a hybrid solution. First try to solve it with minimal memory (store selected pairs on your stack). Once you've hit the first dead end, degrade to doing full marking/edge generation when visiting each node (lazy evaluation where possible).
I've done very little study of graph theory, though, so maybe there's a better solution to the DAG random traversal/search problem :)
Edit: You actually could use any of my solutions w/ generating the board in reverse, ala the Oct 13th 2008 post. You still have the same caveats, because you can still end up with dead ends. Generating a board in reverse has more complicated rules, though. E.g, you are guaranteed to fail your setup if you don't start at least SOME of your rows w/ the first piece in the middle, such as in a layout w/ 1 long row. Picking a completely random (legal) first move in a forward-solving generator is more likely to lead to a solvable board.
The only thing I've been able to come up with is to place the tiles down in matching pairs as kind of a reverse Mahjong Solitaire game. So, at any point during the tile placement, the board should look like it's in the middle of a real game (ie no tiles floating 3 layers up above other tiles).
If the tiles are place in matching pairs in a reverse game, it should always result in at least one forward path to solve the game.
I'd love to hear other ideas.
I believe the best answer has already been pushed up: creating a set by solving it "in reverse" - i.e. starting with a blank board, then adding a pair somewhere, add another pair in a solvable position, and so on...
If you a prefer "Big Bang" approach (generating the whole set randomly at the beginning), are a very macho developer or just feel masochistic today, you could represent all the pairs you can take out from the given set and how they depend on each other via a directed graph.
From there, you'd only have to get the transitive closure of that set and determine if there's at least one path from at least one of the initial legal pairs that leads to the desired end (no tile pairs left).
Implementing this solution is left as an exercise to the reader :D
Here are rules i used in my implementation.
When buildingheap, for each fret in a pair separately, find a cells (places), which are:
has all cells at lower levels already filled
place for second fret does not block first, considering if first fret already put onboard
both places are "at edges" of already built heap:
EITHER has at least one neighbour at left or right side
OR it is first fret in a row (all cells at right and left are recursively free)
These rules does not guarantee a build will always successful - it sometimes leave last 2 free cells self-blocking, and build should be retried (or at least last few frets)
In practice, "turtle" built in no more then 6 retries.
Most of existed games seems to restrict putting first ("first on row") frets somewhere in a middle. This come up with more convenient configurations, when there are no frets at edges of very long rows, staying up until last player moves. However, "middle" is different for different configurations.
Good luck :)
P.S.
If you've found algo that build solvable heap in one turn - please let me know.
You have 144 tiles in the game, each of the 144 tiles has a block list..
(top tile on stack has an empty block list)
All valid moves require that their "current__vertical_Block_list" be empty.. this can be a 144x144 matrix so 20k of memory plus a LEFT and RIGHT block list, also 20 k each.
Generate a valid move table from (remaning_tiles) AND ((empty CURRENT VERTICAL BLOCK LIST) and ((empty CURRENT LEFT BLOCK LIST) OR (empty CURRENT RIGHT BLOCK LIST)))
Pick 2 random tiles from the valid move table, record them
Update the (current tables Vert, left and right), record the Tiles removed to a stack
Now we have a list of moves that constitute a valid game. Assign matching tile types to each of the 72 moves.
for challenging games, track when each tile becomes available. find sets that have are (early early early late) and (late late late early) since it's blank, you find 1 EE 1 LL and 2 LE blocks.. of the 2 LE block, find an EARLY that blocks ANY other EARLY that (except rightblocking a left side piece)
Once youve got a valid game play around with the ordering.
Solitaire? Just a guess, but I would assume that your computer would need to beat the game(or close to it) to determine this.
Another option might be to have several preset layouts(that allow winning, mixed in with your current level.
To some degree you could try making sure that one of the 4 tiles is no more than X layers below another X.
Most games I see have the shuffle command for when someone gets stuck.
I would try a mix of things and see what works best.

Resources