|
里面多了一步去除字符list中0,1,分隔符. 实际上里面不需要特意去0,1,不会影响translate的结果。当然,我的分隔符实际上也是去的,不过是直接通过从分隔符+1开始拼字符串来去掉的。
如果担心因此影响N的取值,也有办法轻松绕过。
- with
- linesrc(line,linenum) as ( -- 生成 01010串
- select replace(linestr,',') line ,to_number(replace(linestr,','))
- from (
- select sys_connect_by_path(bit,',') linestr,level LevelN
- from (
- select 0 bit from dual
- union all
- select 1 from dual
- )
- connect by level <= :n
- )where LevelN=:n
- and length(linestr)-length(replace(linestr,1))=:m -- 每行正好m个球.
- ),
- solution(LevelN ,solutionStrings, cmp1,cmp2,cmp3 ) as (
- select
- 1 --LevelN
- ,line -- solutionStrings
- ,linenum
- ,linenum
- ,linenum * power(10,:n-1)
- from linesrc
- where line>=reverse(line) --预先过滤左右对称
- union all
- select
- LevelN +1
- ,solutionStrings || line
- ,cmp1+linenum
- ,cmp2+linenum*power(10,levelN)
- ,cmp3+linenum*power(10,:n-levelN-1)
- from solution,linesrc
- where
- levelN<:n and
- instr((cmp1+linenum ) || ( cmp2+linenum*power(10,levelN)) || (cmp3+linenum*power(10,:n-levelN-1)) ,:m+1 ) =0
- ),
- solution2(solutionStrings) as( -- original solution
- select /*+ materialize */ solutionStrings from solution
- where LevelN=:n
- ),
- symmtmp(blockN,xo,yo,xx,yy) as ( --base table for 对称判断.
- select /*+ materialize */
- rownum-1 ,mod(rownum-1,:n),floor((rownum-1)/:n) ,
- :n-1-mod(rownum-1,:n),:n-1-floor((rownum-1)/:n)
- from dual
- connect by rownum <= :n*:n
- ), symmsrc(block_org,block_new,symmtype) as ( -- 对称判断表, blockN 是方格位置,bit是 blockN所对应对称点的二进制数字,symmtype是对称方式,共有八种(包括原地??
- select blockN, blockN ,0 from symmtmp -- type 0, self, no symm
- union all select blockN, xx+yo*:n ,1 from symmtmp -- type 1,左右
- union all select blockN, xo+yy*:n ,2 from symmtmp -- type 2,上下
- union all select blockN,yo+xo*:n ,3 from symmtmp -- type 3,对角
- union all select blockN, yy+xx*:n ,4 from symmtmp -- type 4,反对角
- union all select blockN, yo+xx*:n ,5 from symmtmp -- type 5,顺时针 90
- union all select blockN, xx+yy*:n ,6 from symmtmp -- type 6,顺时针 180
- union all select blockN, yy+xo*:n ,7 from symmtmp -- type 7,顺时针 270
- ) ,
- symm_string as (
- select MAX(DECODE(symmtype,0,replace(r,'!'))) tpl0
- ,MAX(DECODE(symmtype,1,replace(r,'!'))) tpl1
- ,MAX(DECODE(symmtype,2,replace(r,'!'))) tpl2
- ,MAX(DECODE(symmtype,3,replace(r,'!'))) tpl3
- ,MAX(DECODE(symmtype,4,replace(r,'!'))) tpl4
- ,MAX(DECODE(symmtype,5,replace(r,'!'))) tpl5
- ,MAX(DECODE(symmtype,6,replace(r,'!'))) tpl6
- ,MAX(DECODE(symmtype,7,replace(r,'!'))) tpl7
- from(
- select sys_connect_by_path(chr(block_new+ascii('!')+1),'!') r ,level as l,symmtype
- from symmsrc start with block_org=0 connect by prior block_org+1 = block_org and prior symmtype = symmtype
- )
- where l = :n*:n )
- select * from
- (select :m M,:n n,
- count(distinct least(
- SOLUTIONSTRINGS
- ,TRANSLATE(tpl1,tpl0,SOLUTIONSTRINGS)
- ,TRANSLATE(tpl2,tpl0,SOLUTIONSTRINGS)
- ,TRANSLATE(tpl3,tpl0,SOLUTIONSTRINGS)
- ,TRANSLATE(tpl4,tpl0,SOLUTIONSTRINGS)
- ,TRANSLATE(tpl5,tpl0,SOLUTIONSTRINGS)
- ,TRANSLATE(tpl6,tpl0,SOLUTIONSTRINGS)
- ,TRANSLATE(tpl7,tpl0,SOLUTIONSTRINGS)
- )) as noReptCnt from symm_string,solution2),
- (select count(distinct SOLUTIONSTRINGS) as all_cnt from (
- select SOLUTIONSTRINGS from symm_string,solution2
- union select translate(tpl0,tpl1,SOLUTIONSTRINGS) from symm_string,solution2
- ))
复制代码
原帖由 newkid 于 2011-3-30 11:27 发表 ![]()
我看了一下其实大同小异,你写得紧凑些,我的行列转换多了一层,因为中间那一层我后面有用(还原所有解法)。
这几个模版怎么折腾,复杂性都有限,开销可以忽略。 |
|