I have a general design question:
There is a junction, with four roads connecting to it. Each road has 2 lanes.
What would be the best way to design a program to handle such junction. It should allow 2 cars 2 go through the junction if they don't interfere each other. and 1 car came in before the other, and they both should use the same part of the junction, the 1st car should get priority. Also, 2 cars may arrive the junction at the exact same time.
What would be the best design for this problem? what exactly should you lock, in order to allow best use of the junction?
Thanks!
Each car should lock parts of the lane it's going to pass trough. If one of the parts is locked then car should wait until it will be released.
What do you think about having 4 different queues for each part of the junction. each car that comes in enters the relevant queue (should enter to more than one queue?), and only after the car leaves all queue it can go through the junction..
Still not sure what is the best implementation for it though.
Create a circle buffer with two entries for each road (one for inbound, one for outbound) meeting at the intersection.
For each car that you have to route put it's name into the circle buffer for its source (inbound) and its destination (outbound). Then iterate through the circle buffer, if you get two instances of the same car together then that car may travel. After that pick at random from the other cars.
I have a feeling that's pretty unclear so consider an intersection with 4 roads that we'll call N, E, S and W. To that we'll have 3 cars, A coming from the East turning South, B from the South travelling North and C from the West travelling East.
Circle buffer can be built as such (i=inbound, o=outbound:
Ni No Ei Eo Si So Wi Wo
B - C A A B - C
As we iterate through from left to right we realise that the two A's are adjacent so they can go but the B's and C's are not adjacent so these cars are block each other. Pick one at random for this light cycle and let the other go in the next light cycle. So either A and B can go or A and C can go.
Note1: testing adjacent ignores blanks so in the case of
Ni No Ei Eo Si So Wi Wo
D E - - E D - -
which models a car travelling North and another travelling South both E's and D's are adjacent.
Note2: I've mapped this out for driving on the left because that's what I do. You'll have to mirror it for driving on the right.
Note3: You can't overwrite a position in the buffer, if two cars want the same destination they're automatically blocking and you should just leave the first one in there and consider the other one next time.
Related
I have a data translation problem, and would like guidance on how I can crack it:
I have an inbound list of items that represent train cars assigned to segments along a journey. Each item has an index, a car reference, an origin and a destination.
E.g.
Index Car Origin Destination
1 C1 L1 L2
2 C2 L1 L2
3 C3 L1 L2
4 C1 L2 L3
5 C2 L2 L3
6 C4 L2 L3
The example above show four cars (C1, C2, C3, C4). Cars C1-C2 travels from L1 to L3. C3 travels from L1 to L2. C4 travels from L2 to L3. The index maintains the order of the cars within each 'leg', but it is relative: For the second leg (L2-L3), the first index in use is 4.
I need to translate this into a different model that provides a distinct list of cars, while maintaining the order of the cars within the train.
E.g.
Index Car Origin Destination
1 C1 L1 L3
2 C2 L1 L3
3 C3 L1 L2
4 C4 L2 L3
The second model doesn't allow for a complete re-ordering of the train cars mid journey. I.e. I can't allow cars A, B, C, D to change order to A, C, B, D. I would have to apply some heuristic to obtain the resulting car order, and it would not reflect reality. I'm happy to accept this drawback.
Also, although the target model index specifies car order within the train, it doesn't matter whether I index from the front or the back of the train. It would be nice to use lower indeces for car assignments earlier in the Journey.
So, for the solution: I think I need to employ graphs to make this translation but I'm unsure where to start. I think I should be modeling a car as a vertex, and a coupling of a two cars in the same leg as an edge. But I'm not sure where I go from there.
I'd be very grateful for any pointers on how to approach the problem: Modelling tips, merging algorithms...
Edit
One more complication: On some legs the order of cars in a train may completely reverse. This is used to indicate the train changed direction. I don't need to capture that reversal, but I do need to retain the inter-connected order of the cars.
In essence, and leaving aside the question of reversed segments, this problem reduces to a topological sort for which a number of simple and efficient algorithms exist (see the Wikipedia link for examples). To construct the graph, we use the cars as vertices and insert an edge from Ci to Cj if Ci immediately precedes Cj in some leg. (This minimizes the number of edges, which reduces the cost of an O(V+E) topological sort.)
But that won't work with "reversed" legs; these will cause the topological sort to fail. So the other part of the problem is to detect reversed legs. Here I'm assuming that there is no definite list of reversed legs; if there were, the solution would be obvious.
I think the following will work reasonably efficiently, but it may well not be optimal.
Let's say that two legs are forward compatible if they share at least two cars and the order of the shared cars is identical in the two legs. Similarly, two legs are reverse compatible if they share at least two cars and the order of the shared cars in one is the exact reverse of the order of the shared cars in the other. Finally, two legs are bidirectionally compatible if they share at most one car. (It's possible that two legs don't fit into any of these three categories, in which case they are incompatible and the problem has no solution.)
It's easy to categorize the relationship between two legs. With the right datastructure (a hashtable, for example) finding the list of shared cars between two legs is O(min(m,n)) where m and n are the sizes of the legs (in number of cars), as is checking if the shared cars appear in the same or reversed order in the two lists. So constructing the entire array of relationships between all possible pairs of legs should be O(L·N) where L is the number of legs and N the number of cars. (I don't have a proof of this assertion, so it could be wrong. But it seems reasonable.)
With the graph of compatibilities, we need to assign a direction to each leg. We do this using a traverse of the graph, using the following recursive procedures:
# Direction is either Forward or Reverse. We assume a function reverse(D) which
# returns Reverse if D is Forward, and Forward if D is Reverse
setDirection(Leg, Direction):
+ If the Direction of Leg is Direction, return.
+ If the Direction of Leg is set and not the same as Direction, fail.
+ Otherwise:
+ Set the Direction of Leg to Direction.
+ For each L such that Leg is forward compatible with L:
+ Call SetDirection(L, Direction)
+ For each L such that Leg is reverse compatible with L:
+ Call SetDirection(L, reverse(Direction))
setAllDirections():
+ while some Leg L does not have its direction set:
+ SetDirection(L, Forward)
Now, we can reverse the order of the cars in the legs which are marked as reversed, and apply the topological sort.
Note that it is possible for the above procedure to a consistent set of leg directions which does not correspond to "reality", because the decision to set the initial direction of a new Leg in the last line is totally arbitrary. But I think it is the best that we can do.
Firstly I'm not necessarily looking for a complete algorithm I can just copy and paste, then call it a day. Any "general approach" solutions would be fine for me!
This entire post was spurred by a slow day at work, and stumbling upon this site and not being able to figure out how they implemented their generator.
The Problem
For those of you who don't know, the "Zebra Puzzle" or "Einstein's Puzzle" is a famous logic puzzle that you've probably ran into before.
The full wiki article is here, but I'll post the relevent bits.
There are five houses.
The Englishman lives in the red house.
The Spaniard owns the dog.
Coffee is drunk in the green house.
The Ukrainian drinks tea.
The green house is immediately to the right of the ivory house.
The Old Gold smoker owns snails.
Kools are smoked in the yellow house.
Milk is drunk in the middle house.
The Norwegian lives in the first house.
The man who smokes Chesterfields lives in the house next to the man with the fox.
Kools are smoked in the house next to the house where the horse is kept.
The Lucky Strike smoker drinks orange juice.
The Japanese smokes Parliaments.
The Norwegian lives next to the blue house.
Now, who drinks water? Who owns the zebra? In the interest of clarity, it must be
added that each of the five houses is painted a different color, and their inhabitants
are of different national extractions, own different pets, drink different beverages
and smoke different brands of American cigarets [sic]. One other thing: in statement
6, right means your right.
This is all well and good. I've found several concise and neat ways online to solve this problem, especially using constraint programming. However, what interests me is making more of these types of puzzles.
Making More
Obviously, a matrix representation is a logical way to think about this. With each column containing a person, house, what they drink, what type of car they drive, etc.
My initial thought was to start with a randomly generated grid that is complete (ie, solved) then (somehow) create hints from the solved version that uniquely identify it. Every time something can be determined, it's removed from the grid.
Ripping off the site I listed at the beginning, the following "hints" that can be used to solve the grid can be of the following type:
The person/animal/plant lives/grows in a given house.
The person/animal/plant does not live/grow in a given house.
The person/animal/plant lives in the same house as the other
person/animal/plant.
The person/animal/plant is a direct neighbor of the other
person/animal/plant.
The person/animal/plant is the left or right neighbor of other
person/animal/plant.
There is one house between the person/animal/plant and the other
person/animal/plant.
There is one house between the person/animal/plan and the other
person/animal/plant on the left or right.
There are two houses between the person/animal/plant and the other
person/animal/plant.
There are two houses between the person/animal/plan and the other
person/animal/plant on the left or right.
The person/animal/plant lives left or right from the other
person/animal/plant.
You can see how these could be generalized, extended, etc;
The difficulty is, using my approach (starting with a complete grid and generating these hints), I'm not sure how to make sure the set of hints I create would absolutely result in the target grid.
For example, if you say "The Englishman does not own a pine tree" you cannot decisively pair two things together at any given time in the puzzle. Yet if there were only two trees remaining to solve for, this could in fact be a decisive piece of evidence.
Am I thinking about this the entirely wrong way?
Would a better approach be to create a grid with some randomized, pre-defined known elements (ie, the red house is in the middle) and then build up the grid using these hints as rules for building?
Any advice, articles to read, programming techniques to learn about, etc. would be greatly appreciated!
Here's a simple algorithm making use of your solver:
Generate a random puzzle instance.
Build a set C of all possible clues that pertain to this puzzle instance. (There are a finite and in fact quite small number of possible clues: for example if there are 5 houses, there are 5 possible clues of the form "Person A lives in house B", 8 possible clues of the form "Person A lives next to house B", and so on.)
Pick a random permutation c1, c2, ..., cn of the clues in C.
Set i = 1.
If i > n, we are done. The set C of clues is minimal.
Let D = C − { ci }. Run your solver on the set D of clues and count the number of possible solutions.
If there is exactly one solution, set C = D.
Set i = i + 1 and go back to step 5.
(You can speed this up by removing clues in batches rather than one at a time, but it makes the algorithm more complicated to describe.)
I'm not entirely confident in this solution but this is how I would approach it:
Starting from a random solution (i.e. green house holds polish that smokes LM, red house holds irish that smokes cloves etc). you may look at that solution as a graph of relations between statements. where every element (polish, red house etc) is connected to all other elements either by a "yes" edge or a "no edge" (in our case the polish is connected to the green house with a "yes" edge and to the cloves with a "no edge" (amongst many other edges, this initial graph is a full, directional graph)).
Now, if you randomly take away edges, until you are left with a minimal connected graph, you should have a graph representing a solvable puzzle. translate every yes edge to "the foo is/does bar" and every no edge to "the foo isn't/doesn't bar".
intuitively this sounds about right to me. but again, this is in no way a formal or recognized way to do this, and may be entirely wrong.
You can also do it the other way around (which will get you a solver as well):
Generate S, a list of all possible solutions (i.e. tables).
Generate a random fact f (for example: the Norwegian has a cat).
Set T = S
Filter out from T all solutions that violate f.
If |T| = 0 then goto 2 (the fact contradicts a previous one)
If |T| < |S| then set S = T and F.append(f) (the fact is not already embodied by previous facts)
IF |S| > 1 then goto 2
Once done - F will be the list of facts that lead to the only table left in S.
Admittedly, this is very much brute force, and will probably not work well with a table that is 5X5 or more.
Interestingly, the "Einstein" Puzzle
(quotes intended, everything "clever" tends to be assigned to Einstein maybe to have more glamour),
is related to Sudoku Generation Algorithm (by a proper translation of terms) and also to Rubik Cube (3x3x3) Solving Algorithm
In the case of Sudoku, the clues correspond to already assigned numbers on the grid and the missing information to empty slots
In the case of Rubik Cube (which i find more interesting), the clues correspond to symmetries of the cube (eg green color is next to red color, sth like that) And the missing data are found by re-aligning (solving) the cube
This is a rough outline, thanks
Here's another thought - once you've generated your complete grid take a photo of it on your phone (Or duplicate the design) before removing items as you provide clues. You might get half way through the task and forget what the original/ final layout is meat to look like and can avoid misinforming your subjects/ test takers.
Thinking of doing one for Easter, similar pattern,
5 people, 5 chocolate types, 5 ages, 5 different Easter hats, 5 different favourite drinks, ice creams etc.
There is a square grid with obstacles. On that grid, there are two members of a class Person. They face a certain direction (up, right, left or down). Each person has a certain amount of energy. Making the persons turn or making them move consumes energy (turning consumes 1 energy unit, moving consumes 5 energy units).
My goal is to make them move as close as possible next to each other (expressed as the manhattan distance), consuming the least amount of energy possible. Keep in mind there are obstacles on the grid.
How would I do this?
I would use a breadth-first search and count a minimal energy value to reach each square. It would terminate when the players meet or there is no more energy left.
I'll make assumptions and remove them later.
Assuming the grid is smaller than 1000x1000 and that you can't run out of energy..:
Assuming they can't reach each other:
for Person1,Person2, find their respective sets of reachable points, R1,R2.
(use Breadth first search for example)
sort R1 and R2 by x value.
Now go through R1 and R2 to find the pair of points that are closest together.
hint: we sorted the two arrays so we know when points are close in terms of their x coordinate. We never have to go further apart on the x coordinate than the current found minimum.
Assuming they can reach each other: Use BFS from person1 until you find person2 and record the path
If the path found using BFS required no turns, then that is the solution,
Otherwise:
Create 4 copies of the grid (call them right-grid, left-grid, up-grid, down-grid).
the rule is, you can only be in the left grid if you are moving left, you can only be in the right grid if you are moving right, etc. To turn, you must move from one grid to the other (which uses energy).
Create this structure and then use BFS.
Example:
Now the left grid assumes you are moving left, so create a graph from the left grid where every point is connected to the point on its left with the amount of energy to move forwards.
The only other option when in the left-grid is the move to the up-grid or the down-grid (which uses 1 energy), so connect the corresponding gridpoints from up-grid and left-grid etc.
Now you have built your graph, simply use breadth first search again.
I suggest you use pythons NetworkX, it will only be about 20 lines of code.
Make sure you don't connect squares if there is an obstacle in the way.
good luck.
I have to make a flash game like this:
There is a board with holes in it (more than 1000). Initially, there are 3 pegs placed on the board and a rubber band around them.
We have 3 possible operations:
1. Add peg - adds a peg on the board
2. Remove peg - removes a peg ( if there are more than 3 pegs) - the rubber band must take the shape of the remaining pegs.
3. Move peg - rubber band must be updated with current positions of the pegs.
How would you solve the problem of finding the rubber band's shape optimally?
I have 2 ideeas, but I have to work on them a little bit. The main ideea is that we have to change the rubber band's shape only at "Move" operation, and we use the same number of pegs, only one is changing position:
A derivation from convex hull algorithm. We have to know wich pegs are inside the rubber band and wich are outside. It might get a little complicated.
We work with only 3 pegs: 2 anchors and 1 middle. The 2 anchors form a boundary line for the interaction of the 1 middle peg. On the active side of the line the rubber band functions as 2 segments between the 2 anchor pegs and the middle peg. On the inactive side the 1 middle peg is free to move while the rubber band functions as a straight line between the 2 anchor pegs. The caveat to the above is that there are cases in which movement of the 1 middle peg in the active side of the boundary line can can cause one of the 2 segments to contact a 4th peg. The program must detect this occurrence and update the new anchor pegs accordingly. These are just suggestions from some limited experience with this concept. The developer should determine the best approach based on his experience and judgement.
Do you have any other ideeas, or suggestions?
"The developer should determine the best approach based on his experience and judgement." — did you copy and paste this from the spec you were given? :)
You ask for an "optimal" solution but if I were you I'd aim for a "correct, and fast enough" solution. You've got a contract to fulfil, you can leave the asymptotics to the academics.
Anyway, your plan to update the band only when the player moves a peg looks like a good one. We are going to need to remember all the pegs that are touching the rubber band, and for each peg we have to remember which side of the rubber band it's on (in order to draw the band correctly).
Now, suppose the player moves peg A from a to a'.
As a general principle, it's worth bearing in mind that even if your time segments are short, and the distance from a to a' is small, nonetheless there might be multiple things that happen. So you're going to have to consider all the events that might happen in that time segment, pick the earliest such event, update your data structures accordingly, and then continue with the remainder of the time segment.
So what kind of events are there?
Peg A "picks up" the band. (It does so if peg A was not already on the band, and the line a–a' crosses one of the lines between pegs on the band.)
Peg A "puts down" the band. (It does so if peg A was on the band, with neighbours B and C, and the line a–a' crosses the line B–C.)
Peg A gains a neighbour on the band. (This happens when peg A is on the band, B is a neighbour of A and the triangle a–a'–B contains another peg C.)
Peg A loses a neighbour on the band. (This happens when peg A is on the band, the neighbouring pegs on the band go A–B–C, and peg B is in the triangle a–a'–C.)
So you should determine all such events; work out the time that each event would happen; sort the events into order by time; handle the earliest event (only); repeat for the remainder of the time segment.
(What to do if two events happen simultaneously? I'll leave that up to your experience and judgement.)
Edited to add: a complication is that a peg may appear on more than one segment of the rubber band (for example, the band may go A-B–A-C-A). But I think the above sketch of an algorithm still works.
A further wrinkle is that even with a small number of pegs, you can make arbitrarily twisty configurations of the band. For example, suppose the band is stretched between pegs B and C. Now take peg A and move it in a figure-of-8 around pegs B and C (clockwise around B, anti-clockwise around C, let's say). Each time round the loop, peg A picks up another couple of pieces of the band. You can't afford to let the complexity of the configuration grow without bound, so need some way of stopping things getting out of hand. I suggest imposing a maximum limit on the length of the band, so that any attempt to stretch it too far causes it to snap (of course you'd have warning signs before this happens, e.g. band getting thinner, changing colour, ominous creaky sounds).
im not too sure how to implement this...
I need to create a weighted directed graph based on the water jug problem from the movie Die Hard 3 (http://www.wikihow.com/Solve-the-Water-Jug-Riddle-from-Die-Hard-3).
I need to create nodes for all the possible moves (fill, empty, pour). After i need to find the shortest path to the solution. But i am have trouble creating this graph. I am using my own created linked list/node.
Any help with the algorithm to create this graph would be great. Thanks.
ex) given 3 gallon, 5 gallon. Get 4 gallons in the 5 gallon jug. I need to create a graph of all the possible moves to get to 4 gallons. Each different gallon represents a different node.
Happy Thanksgiving =)
Presumably each node holds two positive integers -- number of gallons in the 3-gal jug, number of gallons in the 5-gal jug. Arcs, aka edges (directed), are the "moves" (and labeled with the action the arc represents) -- apparently you also have an unnamed tap handy, since you can always fill either of the jugs; you can also always empty a jug away (so you also have a sink); and so forth (other moves all involve moving water from one gallon to the other, until either the first one is empty, or the second one is full). It's no doubt better to avoid generating legal but useless arcs ("moves"), such as "filling" a jug that's already full, or undoing a move you just made (such as emptying a jug you just filled from the tap), though adding such arcs will only mean a little more work, not an incorrect solution.
So start with (0, 0) -- both jugs full, as you have at the start. Clearly the two arcs from here take you to (3, 0) and (0, 5) respectively (filling one or the other from the tap), and so on. Hope this helps!
At each step you have 6 different options
1.A=full
2.B=full
3.A->B
4.B->A
5.A=0
6.B=0
And here you go.
Put states in lookup table and check that none of solution will repeat. This is also stopping condition.
size of lookup table is A * B, and calculating hash is just A*vol(B)+B
In table[A*vol(B)+B] save from witch position you came from.
Make initialisation of table elements on -1 (i supose that first index is 0 in your language)