|
|
本帖最后由 〇〇 于 2021-10-18 10:43 编辑
sqlite的结果是对的,应该是postgresql数据溢出的问题
sqlite> create table chess6 as
...> with t6(n) as (select 1 union all select n+1 from t where n<6)
...> ,
...> b3(a,b,c,bit)as(select a.n,b.n,c.n,(1<<(a.n-1))+(1<<(b.n-1))+(1<<(c.n-1)) from t6 a,t6 b,t6 c where a.n<b.n and b.n<c.n)
...> ,
...> b9(b)as(select c.bit*((1<<(r.a-1)*6)+(1<<(r.b-1)*6)+(1<<(r.c-1)*6)) from b3 c,b3 r)
...> ,
...> t(n,c,x,y)
...> as(select 1,'1',1,1 union all select n+1,cast(n+1 as varchar),n/6+1,n%6+1 from t where n<6*6)
...> ,
...> s(lv,n,nlist,blist,px,py)
...> as(select 1,t.n,t.c,1<<(t.n-1),pow(10,t.x),pow(10,t.y) from t where t.n<=6
...> union all
...> select lv+1,b.n,nlist||','||c,blist+(1<<(b.n-1)),px+pow(10,b.x),py+pow(10,b.y)
...> from s,t b
...> where lv<10 and s.n<b.n
...> --and(blist%19<14)
...> and (instr(px+pow(10,b.x),3)=0 and instr(py+pow(10,b.y),3)=0)
...> --and(select max(sum(case when a.x=b.x then 1 end), sum(case when a.y=b.y then 1 end))from t a
...> -- where ((blist+(1<<(b.n-1))&(1<<(a.n-1)))>0))<=2
...> and b.n between lv/2*6+1 and lv/2*6+6*2
...> )
...> select * from s where lv=10 and (lv<3 or not exists(select 1 from b9 where (blist & b9.b) =0))
...> ;
Run Time: real 537.988 user 535.660634 sys 1.965613
sqlite> select count(*) from chess6;
32400
Run Time: real 0.000 user 0.000000 sys 0.000000
pypy3的sqlite快不少
import time
import sqlite3
con=sqlite3.connect(':memory:')
cur=con.cursor()
t=time.time()
for row in cur.execute('''
create table chess6 as
with t6(n) as (select 1 union all select n+1 from t where n<6)
,
b3(a,b,c,bit)as(select a.n,b.n,c.n,(1<<(a.n-1))+(1<<(b.n-1))+(1<<(c.n-1)) from t6 a,t6 b,t6 c where a.n<b.n and b.n<c.n)
,
b9(b)as(select c.bit*((1<<(r.a-1)*6)+(1<<(r.b-1)*6)+(1<<(r.c-1)*6)) from b3 c,b3 r)
,
t(n,c,x,y)
as(select 1,'1',1,1 union all select n+1,cast(n+1 as varchar),n/6+1,n%6+1 from t where n<6*6)
,
s(lv,n,nlist,blist,px,py)
as(select 1,t.n,t.c,1<<(t.n-1),pow(10,t.x),pow(10,t.y) from t where t.n<=6
union all
select lv+1,b.n,nlist||','||c,blist+(1<<(b.n-1)),px+pow(10,b.x),py+pow(10,b.y)
from s,t b
where lv<10 and s.n<b.n
--and(blist%19<14)
and (instr(px+pow(10,b.x),3)=0 and instr(py+pow(10,b.y),3)=0)
--and(select max(sum(case when a.x=b.x then 1 end), sum(case when a.y=b.y then 1 end))from t a
-- where ((blist+(1<<(b.n-1))&(1<<(a.n-1)))>0))<=2
and b.n between lv/2*6+1 and lv/2*6+6*2
)
select * from s where lv=10 and (lv<3 or not exists(select 1 from b9 where (blist & b9.b) =0))
'''):
print(row)
print(time.time()-t)
395.96064710617065
>>>> for row in cur.execute('''
.... select count(*) from chess6
.... '''):
.... print(row)
....
(32400,)
在postgresql把1<<替换成1::bigint<<就对了
create table chess6a as
with RECURSIVE t6(n) as (select 1 union all select n+1 from t where n<6)
,
b3(a,b,c,bit)as(select a.n,b.n,c.n,(1::bigint<<(a.n-1))+(1::bigint<<(b.n-1))+(1::bigint<<(c.n-1)) from t6 a,t6 b,t6 c where a.n<b.n and b.n<c.n)
,
b9(b)as(select c.bit*((1::bigint<<(r.a-1)*6)+(1::bigint<<(r.b-1)*6)+(1::bigint<<(r.c-1)*6)) from b3 c,b3 r)
,
t(n,c,x,y)
as(select 1,cast(1 as varchar),1,1 union all select n+1,cast(n+1 as varchar),n/6+1,n%6+1 from t where n<6*6)
,
s(lv,n,nlist,blist,px,py)
as(select 1,t.n,t.c,1::bigint<<(t.n-1),pow(10,t.x),pow(10,t.y) from t where t.n<=6
union all
select lv+1,b.n,nlist||','||c,blist+(1::bigint<<(b.n-1)),px+pow(10,b.x),py+pow(10,b.y)
from s,t b
where lv<10 and s.n<b.n
--and(blist%19<16)
and (position('3' in (px+pow(10,b.x))::varchar)=0 and position('3' in (py+pow(10,b.y))::varchar)=0)
--and(select max(sum(case when a.x=b.x then 1 end), sum(case when a.y=b.y then 1 end))from t a
-- where ((blist+(1::bigint<<(b.n-1))&(1::bigint<<(a.n-1)))>0))<=2
and (b.n between lv/2*6+1 and lv/2*6+6*2)
)
select * from s where lv=10 and not exists(select 1 from b9 where (blist & b9.b) =0)
;
SELECT 32400
时间:158262.389 ms (02:38.262)
|
|