Oracle RDBMS 11gR2 – Solving a Sudoku using Recursive Subquery Factoring
Oracle Database 11g Release 2 introduces a new feature called Recursive Subquery Factoring. My collegue Lucas sees it as a substitute for Connect By based hierarchical querying, Oracle RDBMS 11gR2 – new style hierarchical querying using Recursive Subquery Factoring. When I first was thinking about a pratical use for this feature I couldn’t come up with anything, but on second thought:: solving Sudokus!
Say you have a sudoku like:
To solve this sudoku you first have to transforms this to a single string by appending all rows together:
Past this string into a Recursive Subquery, run it and you get a new string with your solved sudoku:
with x( s, ind ) as
( select sud, instr( sud, ' ' )
from ( select '53 7 6 195 98 6 8 6 34 8 3 17 2 6 6 28 419 5 8 79' sud from dual )
union all
select substr( s, 1, ind - 1 ) || z || substr( s, ind + 1 )
, instr( s, ' ', ind + 1 )
from x
, ( select to_char( rownum ) z
from dual
connect by rownum <= 9
) z
where ind > 0
and not exists ( select null
from ( select rownum lp
from dual
connect by rownum <= 9
)
where z = substr( s, trunc( ( ind - 1 ) / 9 ) * 9 + lp, 1 )
or z = substr( s, mod( ind - 1, 9 ) - 8 + lp * 9, 1 )
or z = substr( s, mod( trunc( ( ind - 1 ) / 3 ), 3 ) * 3
+ trunc( ( ind - 1 ) / 27 ) * 27 + lp
+ trunc( ( lp - 1 ) / 3 ) * 6
, 1 )
)
)
select s
from x
where ind = 0
/
This string can be transformed back to a nice display of the solution
So with Recursive Subquery Factoring you can solve your sudokus in 1 statement wich does fit on your screen, not something like in Solving a Sudoku with 1 SQL-statement: the Model-clause
Anton






13/10/2009 - 1:19 pm
Anton:
Really very impressive! Well done.
Lucas
13/10/2009 - 2:08 pm
Wow!
13/10/2009 - 6:16 pm
14/10/2009 - 2:37 am
kudoz, I love it
14/10/2009 - 2:39 am
select rownum lp
from dual
connect by rownum <= 9
but why connect by? it is old fashion
14/10/2009 - 8:32 am
@Laurent: I’ve tried the also some other number generators:
select *
from table( sys.odcinumberlist( 1, 2, 3, 4, 5, 6, 7, 8, 9 ) )
/
select *
from ( with x( r ) as
( select 1 r from dual
union all
select r + 1
from x
where r < 9
)
select * from x
)
/
But, being nearly 50, I stuck with the old fashioned way
22/10/2009 - 12:17 pm
Powerful ! Can call it Art.
22/10/2009 - 3:01 pm
Anton,
We now shall call you a “Sudoku Master”.
Ittichai
31/10/2009 - 2:15 am
fake
31/10/2009 - 5:04 am
Impressive! Shared it on Facebook & Twitter.
31/10/2009 - 8:36 am
BFD, you can cheat at a game.
31/10/2009 - 2:08 pm
I wonder what happens if you input a Sudoku that has no solution like
‘ 1 2 1 2 2 1 2 1 ‘
31/10/2009 - 2:11 pm
Hm. Seems that the comment system ate the spaces.
‘…………………1.2…..1…2………….2…1…..2.1…………………’ (replace dots with spaces)
31/10/2009 - 8:56 pm
C.J. Date would not approve of this abuse.
1/11/2009 - 1:08 am
It’s Beautiful.
1/11/2009 - 9:31 am
its great , shared on wykop.pl
1/11/2009 - 1:56 pm
Haha… Great.
1/11/2009 - 2:48 pm
“Anton,
We now shall call you a “Sudoku Master”.”
Agreed
1/11/2009 - 4:24 pm
Very impressive!
1/11/2009 - 5:27 pm
that is a genius solution. what happens if the Sudoku has no solution?
2/11/2009 - 6:52 am
yes! very impressive indeed…
2/11/2009 - 10:30 am
Me too impressed
2/11/2009 - 4:25 pm
@chithanh and @club penguin toys
If the Sudoku has no solutions the result of the query is “no rows selected”. But it can take a lot of time before you get that result, I stopped it after 5 minutes using the suggestions of chithanh.
If the sudoku has more solutions, every solutions is shown.
3/11/2009 - 3:05 pm
Can you do this with MySQL?
3/11/2009 - 9:51 pm
@Dan
I don’t know anything about MySQL, but I don’t think this query will run unchanged on any database except the latest Oracle 11gR2.
5/11/2009 - 10:06 am
Great work!
Your work has been ported to PostgreSQL as well: http://wiki.postgresql.org/wiki/Sudoku_puzzle
6/11/2009 - 12:12 pm
Ported using T-SQL @ http://michaelhthomasblog.blogspot.com/2009/11/solving-sudoku-using-recursive-common.html
Thank you Anton for the solution.
6/11/2009 - 1:01 pm
I had no idea that Oracle was so late with its recursive queries. Those ports in PostgreSQL and T-SQL look very similar to my solution. I’m impressed, both by the possiblities from those languages as by the porting qualities of Frank and Mike.
7/11/2009 - 12:49 pm
Thanks for your Excellent solutions…now i can win sudoku game
9/11/2009 - 10:46 am
For PostgreSQL, the credits go to Marcin Mank, I only linked to the wiki…
12/11/2009 - 12:26 am
Very genius Anton! My good friend, ex-colleague
2/12/2009 - 12:55 pm
Really amazing !
11/12/2009 - 4:20 pm
how ever this dosen’t resolve all the sudoku types ..maybe just the easy ones.. for a more detailed explanation check this sudoku solver that also contains some strategies used by sudoku experts. http://www.scanraid.com/sudoku.htm . For example i dunno how your algorithm would resolve the Intersection Removal Strategy called also the Pointing Pairs Strategy.
11/12/2009 - 11:28 pm
My method solves all sudokus. It’s a brute force solver, so it doesn’t need any clever strategies.
13/12/2009 - 2:41 am
Inspired by your example, I did the Tower of Hanoi:
with h(x, n, a, b, c) as (
select 0, 3, ‘A’, ‘B’, ‘C’ from dual
union all
select x+m*power(2,n), n-1, decode(m, 1, b, a)
, decode(m, 1, a, c), decode(m, 1, c, b)
from h, (select -1 m from dual union all select 1 from dual)
where n > 1
)
select ‘move disk ‘ || n || ‘ from ‘ || a || ‘ to ‘ || c solution
from h order by x
;
22/12/2009 - 12:12 pm
Its brilliant effort, I tried to convert sudoco query in 10g but I am not getting the correct result..Anybody can help me?????
22/12/2009 - 3:00 pm
@W.G. Nice
@Bijesh K Recursive subfactoring is something Oracle introduced in 11GR2, so you can’t convert this kind of solutions to 10g.
31/12/2009 - 9:09 pm
It looks to me that what the recursive subquery does is “breadth-first search”, i.e., for each blank square in the sudoku, it considers all possibilities before moving on to the next blank square. That computes all solutions to the sudoku, but I’m wondering if that is a good way of solving a sudoku in practice because it generally suffices to find one solution.
4/1/2010 - 3:53 pm
@c: Maybe it suffices to find one solutions, this query finds all solutions. And that has nothing to do with breadth- or depth-first searching, that’s because there’s no way to stop the recursion after finding a solution.