- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
What is that horrible language JAVA 6 has posted in? Looks a bit like c#, but isn't. Java, maybe?
I'd like to know so I can avoid RIDICULOUS ANONYMOUS FLAMEBAITERS in my online life.
Admin
I rather liked my solution, which simulates reality by randomly moving the blank square around until you happen upon a solved puzzle.
Only took it 68 seconds real time the first time to solve it!
Admin
DailyWTF people (Alex, et al): I respect you for this. If I was unemployed, I would probably try to solve these puzzles just to put my skilz out there. As it is, I do have a job, and therefore cannot devote my time to this trivia. Sorry.
Addendum (2009-09-02 17:51): Sorry also for those who can.
Admin
I'm not going to lie, if I didn't have an existing (provably optimal) solution sitting around, I wouldn't be solving trivia problems either.
Admin
Pascal rocks, its just a lot better than C as language. And the Delphi compiler generates smallest and faster binaries than the C++ compiler. I had to say it, benchmarks dont lie.
Admin
He is leet ... the rest of us only understand XOR swap !
Admin
Admin
One of the solutions on page 2 made my browser (firefox 3.0.x, haven't upgraded to 3.5 because it crashes thanks to my workplace's "monitoring" software) show a huge black square instead of the person's post, which turns into readable text sometimes if you do a select all. Weird.
Admin
I bet none of you can solve this in LOGO. By having the turtle draw the entire thing.
Admin
Admin
I prefer a Pandora of WTFs; it sounds inappropriately erudite.
Admin
Admin
This finds the optimal solution by a width-first search.
Because many boards have no solution, the generateInput() method creates a board by starting with a solved board and sliding up to 50 times at random.
Sample output:
START FROM |1|2|3| |4|5|6| |7|8|-|
RANDOMIZE INPUT |8|1|-| |4|2|5| |3|6|7| ------- -> (33 moves) 8,5,2,3,6,2,3,6,2,8,5,3,6,1,4,6,1,2,8,1,3,7,6,3,2,8,1,5,7,6,3,4,8,1 OUTPUT |1|2|3| |4|5|6| |7|8|-| ------- -> (21 moves) 5,2,6,3,4,8,1,5,2,6,3,7,6,3,8,4,7,8,5,2,3,6
Code:
Admin
Quite normal for Firefox. It does that often on such long pages.
Admin
the real WTF is why are you putting exercises on this website? Create a new category, stick them in there, and keep up with the real WTF.
Admin
For an interesting experiment I first tried solving this using the "methinks it's a weasel" sort of evolution simulation, but I couldn't find a good way of scoring the comparisons well. They kept getting stuck in a situation where all of the spots surrounding the blank were solved so it'd move away from that and then right back to it; there was no incentive to deviate further away from the solution in order to get it solved.
Anyway, abandoned that eventually and made an inefficient iterative optimal path algorithm. So it's "DIFFICULT" but not "FAST". It does at least make sure it's not repeating its work.
This is the single character variable names version that keeps a bit of formatting but still sneaks in under 800 bytes ;)
Admin
the real WTF is to write something before reading anything
...
Sliding Around 2009-09-02 by Alex Papadimoulis in Bring Your Own Code
Admin
Further, you seem to be dividing solutions into 2 categories polynomial-time (efficient) and brute force. This is nowhere close to reality. Many advanced search techniques cut dramatically down on the algorithmic complexity, but still remain non-polynomial time. Specifically I can think of several SAT solvers that can return, in a matter of minutes solutions that would take a brute force algorithm several universelifes to stumble upon.
Even in computer science an algorithm is called 'efficient' when it performs reasonably well in comparison with other options, regardless of its actual running time.
Admin
Quickly hashed together code gives me these answers.
When the empty tile is in one of the 4 corners, then the maximum depth is 31 moves, and there are 2 starting states at this depth. As there are 4 corners, then this means 8 starting states.
When the empty tile is in one of the 4 edges, then the maximum depth is 31 moves, and there are 2 starting states at this depth. As there are 4 edges, then this means 8 starting states.
When the empty tile is in the center square, then the maximum depth is 30 moves, and there are 26 starting positions at this depth.
Admin
I hate replying to myself, but I just noticed these ...
8 = 3^2 - 1 26 = 3^3 - 1
I wonder if this is a formula for stating states that could be expanded to larger dimensions like 4x4 and 5x5 ? Maybe something to do with the distance that the empty square is from the center of the puzzle ?
Admin
Here's a slowish Python program that finds the shortest solution. If the starting position is unsolvable, it transposes the goal.
Admin
Which C++ compiler? There are a great many.
Admin
Mathematical proof that there are impossible starting configurations:
We will impose a linear ordering upon the pieces in the puzzle: we'll treat it as a paragraph of text, reading row by row top-to-bottom, left-to-right within each row. The solved puzzle state can be read as "123/456/78#". With this order, we can naturally say that the "3" piece comes "before" the "4" or the "6", but not the "2"; and we can say that the "5" is "inbetween" the "2" and the hole.
For any state of the sliding puzzle, you can give a "score" to an unordered pair of two pieces as follows: if the lower-numbered piece comes "before" the higher-numbered one, the pair has a score of 1; otherwise, it has a score of 0.
We define the score of a 3-by-3 puzzle state as the sum of the scores of the 28 pairs. For example, the solution state "123/456/78#" has a score of 28. The puzzle state "876/543/21#" has a score of 0, and the puzzle state "135/7#2/468" has a score of 22.
If I transition from state P to state Q by a single horizontal slide, then each of the 28 pairs in state P is in exactly the same scoring orientation as the 28 pairs in state Q. For example, "123/456/78#" has the same score as "123/456/7#8".
Now consider the transition from state P to state Q by a single vertical slide of piece A. In state P, there are two pieces "inbetween" piece A and the hole; call them B and C. Both of the pairs (A,B) and (A,C) flip their scoring orientation between states P and Q; the other 26 pairs keep their scoring orientation.
Therefore, if one can move from state P to state Q as the result of a single slide, then the difference "score(P)-score(Q)" must be one of -2, 0, or 2.
Therefore, as the result of any number of slides, the score of the initial state and the score of the final state must have the same parity modulo 2.
As shown earlier, the solution state's score is 28.
The score of the state "123/456/87#" is 27.
Therefore, no sequence of slides can convert "123/456/87#" to "123/456/78#".
Admin
I should send the requirements to our Indian outsourcing team... Those fuckers write ( read cut 'n paste ) beautiful solutions and get it right first time!!!!!!!!!!!!
Admin
Here's a python version that's under 800 bytes. Sample usage: python unscramble.py '67143528 '
Admin
I propose the collective noun for WTFs should be 'swamp'.
Admin
One way of solving it is to see that the numbers can still be in the right order, only rotated. Reading clockwise 1, 2, 3, 6, 8, 7, 4 around the edges with 5 in the center is almost completly solved. 4,1,2, 7,5,3, 8,_,6, is almost totally solved.
Once an edge row or col. has been finished. It can be left alone.
You can use the center to store a peice and then insert it (counter)clockwise of the proper piece. (Note: my puzzle has a gap in the top left, not bottom right. And its a frog. The clockwise order is 1,2,5,8,7,6,3, with 4 in center) _,7,6, 8,1,5, 4,3,2,
7,6,5, 8,_,1, #1 and 2 and now in order. 4,3,2
5 is not in the best spot right now, so I'll go for 8 I slide 8 into the center.
7,6,5, _,8,1, 4,3,2,
then free up the spot clockwise of 2.
7,6,5, 4,8,1, 3,_,2,
and slide 8 in
7,6,5, 4,_,1, 3,8,2,
remember I want the order to be 1,2,5,8,7,6,3 6 will fit in nicely now.
7,_,5, 4,6,1, 3,8,2,
7,5,1, 4,6,2, 3,_,8,
7,5,1, 4,_,2, 3,6,8,
5 is now is a spot where it can slide into the center.
7,_,1, 4,5,2, 3,6,8,
I want the order to be 1,2,5,8,7,6,3 so
7,1,2, 4,_,5, 3,6,8,
Almost there, I have one vertical row done. (2,5,8) I can leave this intact and only move the 5 pieces on the right
I bring 1 and 4 to the top and leave them there while I fix the other pieces
7,1,2, _,4,5, 3,6,8,
1,4,2, 7,_,5, 3,6,8,
I rotate the three bottom left pieces untill they are like this
1,4,2, 3,_,5, 6,7,8,
I bring down 1 and 4 to finish
_,1,2, 3,4,5, 6,7,8,
Now I'm off to try and get that to work in python.
Admin
That must have been a Freudian typo! I just remembered that I read that some guy threatened to sue Alex for using the name Programming Praxis, which must be why he changed it.
captcha: zucchinifelatio
Admin
The function assumes a string input of the numbers 1-8, and a 0 representing the empty spot. It outputs which number you should slide. Using an iterative version of a BFS (it did say write a function, not functions :) it finds the fastest way to solve the entered puzzle.
And yes, it's in C#. THE HORROR!
Admin
Imho recommending a less structured programming language to someone because they don't understand the syntax of a more modern language is bad advice.
In the realm of practical languages, Excluding any esolang and parser written for fun, a more interesting question is why would someone bother to write a syntactic construct like that ?
How did they manage to convince anyone else to use it ?
Perhaps the problem is common enough and someone else has thought about it before ?
What were they thinking ?
Admin
Well, I didn't bring my own code, but anyway, this one is from Bratko's Prolog programming for AI. The heuristic is simple but pretty good, so I guess it falls into the difficult category.
Mike5
Admin
Collective noun
A ==== of WTFs
puddle mess crapload sadness woeful
Admin
Yeah, that's why you should not only fire people who can't read requirements, you also need to fire people who can't write requirements.
Admin
A* with ruby:
Admin
Teaching the professor something always gets you an F.
Admin
Admin
Easy.
He didn't have to write the algorithm for solving the thing.
Admin
This should work.... Puzzle class not included, but you'll get the idea.
Admin
"interesting"
Admin
dijkstra in c++
Admin
So what are the chances of Alex sending a WTF mug to the first person to offer a solution using Brainfuck? ;)
Admin
Admin
:oD I like cluster!
Admin
My turtle's hard at work on the problem right now. I'll let you know how he gets on when he's finished in around 215 years' time.
Admin
Admin
Even using INT21h? You're doing it wrong. Shouldn't be more than about 20-30B, compiled. Or about 80 bytes of source.
Admin
So how fast do these "optimal" solutions go?
I've done an A* implementation in C++ which completes in 0.34 seconds. Is that good or bad?
Admin
How fast your solution goes is highly dependent on your processor and how far away the solution is away from the goal.
.34 seconds is about on par for an A*, IIRC. I want to say that I've seen .16 worst time for the 3x3. A better test, however, is to test your solution on a 21x21.
Admin
I'm too lazy to see if this works in all cases, so I'll do what MS does:
Here's the public release, and it will be the richest and most secure Sliding Problem solution ever. (Service Pack 1 to follow)
In SQL.
SET NOCOUNT ON
-- User defined variables DECLARE @GiveUp int -- When to give up DECLARE @OpeningPosition varchar(9)
-- Making-life-easier variables DECLARE @ZeroPos int -- Current position of the space DECLARE @CurrVal varchar(255) -- The current board DECLARE @LastMove int -- The last move taken (so you don't just move the same piece over and over) DECLARE @moveNum int -- The current move number (loop variable)
-- Play history DECLARE @CharBoard table (vals varchar(9), lastMove int, moveNum int identity (0,1) primary key) -- feel free to turn this into a perm table to use an index on vals
-- Set variables here SET @GiveUp = 50 -- how many moves to try before the program gives up SET @OpeningPosition = '123456708' -- The initial position of the 3x3 board, from top left, with 0 being the empty space
-- Initilize board
INSERT INTO @CharBoard values(@OpeningPosition, 0)
SET @LastMove = 0 set @moveNum = 0
-- If we haven't given up, and a solved board doesn't exist yet WHILE @moveNum < @GiveUp and not exists (select top 1 1 from @Charboard where vals = '123456780' order by moveNum desc) BEGIN
END
select case when @MoveNum >= @GiveUp then 'Fuck it, I''m done' else 'Victory is mine!' end as [Result] select moveNum as [Move Number], lastMove as [Piece moved], vals as [Resulting board] from @CharBoard
Admin
Using breadth-first search: