 |
|
 |
Nice article. You might want to fix your link though. It points to: "htpp://www.ganaye.com/macmahon"
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook
"There is no wealth like knowledge, no poverty like ignorance." Ali ibn Abi Talib
"Animadvertistine, ubicumque stes, fumum recta in faciem ferri?"
|
|
|
|
 |
|
 |
I changed my host.
The link is dead I am afraid.
|
|
|
|
 |
|
 |
howdie
Using a metric tensor I came up with 5784 solutions in 18 seconds.
I'm unsure how everyone is getting more unique solutions ??
I think my approach is a bit different.
I'll post more about it in a few weeks when I get time.
Regardz
Colin J Davies
The most LinkedIn CPian (that I know of anyhow)
|
|
|
|
 |
|
 |
I had a look at what a metric tensor is...
I am a bit ashamed to say that it was far too mathematical for me.
I still don't really know what it is.
If you go in http://www.ganaye.com/macmahon/solutions.htm[^]
And view the source of the page you will get the 26656 solutions we found.
They are listed using the syntax I tried to explain in the article.
Currently I think I have the fastest algorithm with 1.2 seconds.
Can you send me your program ?
pascalcp ganaye.com
Replace with @
|
|
|
|
 |
|
 |
I was a bit a upset to be behind with my 5 minutes solution.
So I thought and thought again...
...It took me some time. Every optimization I found for a while was SLOWING down the program
I thought again.
I had an optimization from a while ago which I did not want to write because it was a bit complex...
I just did write it.
It find the 26,656 solutions.
If you add the mirror solutions you get 26,656 * 4 = 106,624.
The program runs in in ... 1.2 second on a Pentium 1.8 Ghz.
I am still a bit in shock.
|
|
|
|
 |
|
|
 |
|
 |
I am happy to see that we have contribution in VB, C# and C++.
Thank you all for your time.
All of us had a good laugh.
We all improved significantly the program I gave at the beginning of this project.
It used to run in more than 24 hours on my machine.
The speed improvement however were not all language related.
For those involved, I think it is pretty clear that the language have a part in speed but not nearly as much as your algorithm.
I worked years in C++, Delphi, VB.Net, Lisp, PHP, Javascript, Progress L4G and I probably forgot some already.
I think that any language is worth a try; each has its little thing it does better than the rest.
You can't always win. This is true for languages as for most things.
All languages are not created equals.
However...
I have a dream that one day on the forums of code project old C++ programmers, Java aficionados and VB enthusiasts will be able to sit down together at a table of brotherhood. I have a dream that one day even the heart of Assembly programmers, the worst really, will be transformed into an oasis of freedom and openness. I have a dream that my programs will one day live in a world where they will not be judged by the color of their lines but by the content of their character.
I have a dream today.
More seriously
I think it is time now to close the contest and publish our respective results.
I suggest Saturday 9th at midnight GMT.
Tell me if you want an extension.
Please send me your projects to: pascalcp ganaye.com
(Replace the by @)
Once published we could change the competitive contest into a collaborative work and try to use each other optimisation.
I think it is time to enter this collaborative phase.
Today...
|
|
|
|
 |
|
 |
pascal wrote:
"I have a dream that one day on the forums of code project old C++ programmers, Java aficionados and VB enthusiasts will be able to sit down together at a table of brotherhood."
keep dreaming
|
|
|
|
 |
|
 |
I've just coded a simple "brute force" alorithm using C++, it just places each piece in turn going through all the valid pieces/and places.
It takes 170 seconds to find all the 106,624 solutions (on a 2.5Ghz P4).
Jon
|
|
|
|
 |
|
 |
Sweet jesus, 170 seconds. That is blazing fast.
Maybe they should all be tested on the same machine though.
I'll volunteer my PIII 500, it'll probably take overnight though LOL.
|
|
|
|
 |
|
 |
Realised I wasn't doing much with the answers, so I added some code to dump the solutions to a file, the time has gone up to 175 seconds.
If you want an exe to test I can email you one - it's only 60k.
Jon
|
|
|
|
 |
|
 |
This is very good.
Why do you return all solutions ?
You could divide by 4 by just removing the mirror solutions.
I think we all agree that any solution can be mirrored 3 times.
So you could limit the location of big red cell to the upper left corner and make your program run in probably less than a minute.
|
|
|
|
 |
|
 |
Jon wrote:
It takes 170 seconds to find all the 106,624 solutions (on a 2.5Ghz P4).
Very impressive. Would you be willing to email me the code?
Thanks!
Marc
MyXaml
Advanced Unit Testing
YAPO
|
|
|
|
 |
|
 |
With two simple optimizations. One optimization you know about--eliminating redundant rotations.
I haven't forgotten about working on this, I just wasn't happy with 30 minutes to come up with the solutions for 1/4 of the puzzle. I coded up a very simple optimization this morning that solves for 1/4 of the puzzle in 67 seconds on my machine. Now I'm happy.
I'll write up the algorithm this weekend.
Marc
MyXaml
Advanced Unit Testing
YAPO
|
|
|
|
 |
|
 |
You can be.
I did not work on it.
I thought 30 minutes was good !
I found an optimization and is now at 12 minutes...
67 seconds...
I hope everyone understand by now that this is not a language contest but an algorithm and optimization contest.
I do love this.
I don't give up though
Here are my optimizations so far:
Optimization 4 - Improve the path
While filling the board, let say I use this path (01 to 24)
02 03 04 05 06 07
01 17 20 21 24 08
16 18 19 22 23 09
15 14 13 12 11 10
First I circle around the board, this way I exhaust the cells containing red very
fast.
This way the program get stuck faster and therefore hopefully has to resolve the
issues earlier.
I think it improve the overall speed.
Optimization 5 - Use a linked-list for the list of squares.
I noticed the program spend lots of time in this loop:
For Each sq As square In squares
If sq.OnBoard = False Then
...
End If
Next
Using a linked list we could speed up this loop
Optimization 6 - Put the red first in the list
Optimization 7 - Add a notion of number of blue/white/red triangles in each piece.
Also add a notion of number of blue/white/red needed in each board location.
This way I can check if the piece can go in a place without having to rotate it 4 times.
This optimization made my program go from ~30 min to ~12 min.
|
|
|
|
 |
|
 |
Interesting optimizations. I like your #4 optimization--I didn't even think about solving the problem in a non-row by row manner. This would cause some problems with my algorithm though, because I use 9 lists keyed on the right and bottom edges of the left and top tiles. But the real magic was in figuring out a trick that eliminates most of the tiles that can go into those 9 lists.
Your linked list idea is cool too. Completely eliminating testing for whether a tile is in use or not would be interesting. Though I wonder if the tradeoff with adjusting the linked list would be worth it.
Marc
MyXaml
Advanced Unit Testing
YAPO
|
|
|
|
 |
|
 |
67 Seconds,
I am still in shock.
I am trying hard to improve the algorithm.
It can't be the language or is it
I find the solutions in 5 minutes 45 seconds at the moment.
Still fighting.
|
|
|
|
 |
|
 |
I see from the updates to the article that Marc Clifton wrote a C# algorithm to perform this task - I'd rather like to see the algorithm - any chance it could be posted or already is and I just haven't bothered to look at the C# algorithms section?
|
|
|
|
 |
|
 |
We will both publish our program later this week I think.
|
|
|
|
 |
|
 |
I found 7 optimizations to speed up the program:
Here are the first 3
2005 march 14 : First release
Optimization 1 - Limit rotations.
It is a bit dumb to rotate some of the squares.
- 3 are single color so rotating them 90, 180 or 270 degrees won't change a thing.
- 3 are like a bow tie so rotating them 180 is useless to.
Optimization 2 - Limit mirror solution
Each solution of the MacMahon problem can be mirroroed against the horizontal axis,
the vertical axis or both.
If we limit the position of one of the square to the 6 cells on the Upper Left part
of the board then we avoid these mirror solution.
o o o . . .
o o o . . .
. . . . . .
. . . . . .
In the program I chose to limit the RED plain square to this area. Then every
solution can be counted as 4 solutions, however I chose not to count the mirror
solutions.
Obtimization 3 - Limit the location of the Plain Red even more
There is 18 cells containing red.
As we know 16 of them have to be in the border of the board.
a b c d e f
g . . . . l
m . . . . r
s t u v w x
Therefore only two cells containing red are present in the 8 locations in the middle.
From that we can prove that the Plain Red square can't go in the location h-k or n-q.
. . . . . .
. h i j k .
. n o p q .
. . . . . .
If the plain red cell was in the (h) location then it would need a cell containing
red in (n) and (i).
And we already know that only 2 cells containing red can be in the center cells.
Also, if we had the plain red cell in (i) then we would need a cell containing red
in (h) (o) and (j).
Ultimately the plain red cell can go only in (a) (b) (c) or (g).
a b c . . .
g . . . . .
. . . . . .
. . . . . .
I will post that in the article tonight, I want to add pictures to this.
|
|
|
|
 |
|
 |
I posted the 26656 solutions I could find on this page:
[^]
I believe that any other solution is a mirror or rotation of one of them but I am not sure.
I started a notation structure for the solutions.
If you name the piece A0,B0,C0,...X0.
The rotated version of B0 would be called B1 (90 degrees),B2 (180 degrees) and B3 (270 degrees).
Then a solution could be written as a simple line like this:
B2D0I0L0J0G0A0C2V0S0T2O3K0F0X0W0U0Q3H2E0P2R2M2N3
|
|
|
|
 |
|
 |
I let my solver run overnight, and it wasn't anywhere near finishing. I think trying to find all the solutions when counting all the symmetric rotations of a tile is rather pointless. A person usually wouldn't consider that a solid square can be rotated four different ways, and that it represents four different solutions.
What do you think?
BTW, what optimizations did you make? Have you updated the download with them?
Marc
MyXaml
Advanced Unit Testing
YAPO
|
|
|
|
 |
|
 |
It is interesting this is my first optimization too.
It cuts a lot.
With another optimization you can limit the location of the Plain Red Piece to 4 locations.
Once done I found 106624 solutions in 90 minutes or so.
|
|
|
|
 |
|
 |
pascal ganaye wrote:
It is interesting this is my first optimization too.
Besides ignoring rotations that are visually the same, I did two other optimizations:
There are 18 tiles with red edges, and 16 positions in which they must be placed. Therefore, if placing a tile that contains a red edge causes the remaining number of red-faced tiles to be less than the remaining number required, then there is no point in continuing recursing through the remaining empty slots on the board because you are guaranteed of a failure. This optimization was a good gain improvement.
The second optimization was to reduce the tile and orientation search list by precomputing the tiles and orientations for the 9 possible upper left edge matches. The resulting sets consist of 9 tiles (I think, I haven't inspected each set) and their rotations are known. Therefore, the search algorithm can look through a list of tiles guaranteed to match in configuration and rotation. The only test that needs to be made is whether the tile is in use or not and whether the right and bottom edges match. This optimization resulted in blazing fast performance.
Your tile labelling scheme is great. When I have time this weekend I'll output my solution set, each solution as a single string. Then we can compare solutions. Should be interesting!
Marc
MyXaml
Advanced Unit Testing
YAPO
|
|
|
|
 |
|
 |
This is fun.
We can't seem to be able to get the same numbers.
I think there is 106624 solutions.
That is 26656 original solutions
+ 26656 mirrored on X
+ 26656 mirrored on Y
+ 26656 mirrored on X and Y (same as rotating 180 degrees I think)
--------
TOTAL 106624
I will post the solutions I found on the article main text.
|
|
|
|
 |