michthro
Level: Smitemaestro
Rank Points: 679
Registered: 05-01-2005
IP: Logged
File: OrbSolver.exe (96 KB) Downloaded 507 times. License: Public Domain
|
Re: Orb solver program (+12)
Here's another one. It uses an efficient algorithm (something like O(n^2.5)) that systematically solves the problem, rather than doing a brute force search, so it's very fast. (The 25 gate problem takes a split second.) It's written in VC++ .NET, so I'm afraid it'll only work on Windows. Maybe someone could build a version for other platforms - Only the I/O uses Windows stuff, so it should be easy enough. If anyone's interested in the source, for whatever reason, I'll be happy to tidy it up a bit and post it. Please just ask. I don't mind at all, but I do mind doing it if no-one's going to even look at it.
Using the program:
It's a stand-alone .exe, so just put it anywhere and run it.
Enter the initial orb configuration in the format OCCOOC... (Not case-sensitive.)
Ditto the target configuration.
Orb actions are entered as follows: (using Open, Close, Toggle and Leave).
-You can type something like O1 C3 T5 O6 4 C7 8, which would mean open 1, 4 and 6, close 3, 7 and 8, and toggle 5. (So you don't have to repeat symbols, and the numbers can appear in any order. You can also leave spaces or not, and it's not case-sensitive.)
-You can also type something like OLCOTOCC for the same effect, but generally, the first format is much more convenient.
-Each orb must go on a separate line. You can leave blank lines, but you can't break an orb's line.
I think you get the idea, but just say if it's not clear. Please let me know if there's a problem. Comments and suggestions welcome.
The algorithm:
I'm only giving a brief outline. Again, just ask if you'd like more detail. The basic idea is that we can repeatedly reduce the puzzle to a smaller one by finding an orb (or combination of orbs) we may as well hit last, removing doors corresponding to Os and Cs from the problem, and toggling target entries corresponding to Ts. What's more, finding such an orb is a matter of solving a system of linear equations.
More exactly: Let's call an orb "good" if it contains at least one O or C, and every O or C is equal to the corresponding entry in the target. Call it "bad" if it has some O or C that does not equal the corresponding entry in target. Otherwise (i.e. when it contains no Os or Cs), call it "ugly" (it's an appropriate term.)
Now, assume there is a solution:
First, suppose there is a good orb: There's no harm in appending a good orb to any solution (we may have to hit it twice to eliminate it's toggles). On the other hand, if we're going to hit it last, we can remove doors corresponding to Os and Cs, since this last hit is going to fix them. So (remembering to toggle target entries corresponding to Ts) the problem reduces to a smaller one.
Otherwise, maybe we can solve the whole problem in one go using only the ugly orbs. There is such a solution if and only if the matrix equation Ax = I+T has a solution modulo 2, where the columns of A are the ugly orbs (with Ls changed to 0s and Ts changed to 1s), I is the initial configuration (with Os changed to 0s and Cs to 1s) written as a column vector, and T, similarly, the target configuration. This equation is easily solved using Gauss-Jordan elimination.
Otherwise, there must be some bad orb that can be turned into a good orb by following it with some ugly orbs. (Just consider any solution: There are no good orbs, not all orbs are ugly, so take the last bad orb. If the orbs following it don't turn it into a good orb, the solution isn't a solution after all.) Again, we can find such a bad orb by solving the equation A'x=B'+T' for every bad orb B, where A and T are as before, except that rows corresponding to Ls and Ts of B are removed, and B' is B with Ls and Ts removed, Os changed to 0s, and Cs changed to 1s.
So, in all cases we can either solve the problem directly, or reduce it to a smaller problem. (Note that bad orbs can become good in the smaller problem etc.)
That's the gist of it. I'm working on a version of the program that will show all possible solutions, if anyone's interested. (It's mainly just a matter of it not stopping when it finds a solution.)
EDIT: Update. Fixed a potential memory problem.
EDIT: It's written using .NET 1.1. Sorry if that's bad.
[Last edited by michthro at 04-05-2006 08:45 AM]
|