用SQLPLUS解决数独问题

数独相信大家都是早有耳闻,sudoku,源于日本的一个小游戏。但是用Oracle来解决数独问题,你相信吗? 第一次听说用Oracle的SQL PLUS居然也能解决数独问题。今天在asktom上看到一个帖子,Anton同学利用Oracle 11gR2的feature Recursive Subquery完美了解决了这个问题。

请看题目:

puzzle

思路:
把所有的数字连成一个字符串,记得空用空格替代,于是变成了

“53 7 6 195 98 6 8 6 34 8 3 17 2 6 6 28 419 5 8 79″

解决方法:


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
/

运行结果如下:

solve

最终数字填充进去就是:

solution

思路和模型在这里

完美!

No Comments

(Required)
(Required, will not be published)