|
下面做些人肉分析,以避免做很多无用功。
我们看看1000以内符合条件的三个数,前两个数是3,7的有:
3 7 109
3 7 229
3 7 541
3 7 673
3 7 823
既然第4个数与前三个数并到一起都必须是质数, 因为其它数都与3或者7冲突, 所以第4个数必然要在上面列表的第三个数中选取, 因此不必再去到所有质数中去寻找。
这样, 对于 (3,7,109), 我们只要在229/541/673/823中逐个测试即可。
用这种方法,写出下面的SQL:
with t as (select /*+ MATERIALIZE */ column_value p from table(pkg_prim2.seive_numlist(10000)) where column_value not in (2,5))
, t2 as (select t1.p p1, t2.p p2 from t t1, t t2
where t2.p>t1.p
and pkg_prim2.isprim(t1.p||t2.p)=0 and pkg_prim2.isprim(t2.p||t1.p)=0)
, t3 as (select t2.p1 p1, t2.p2 p2, t3.p2 p3 from t2, t2 t3
where t3.p1=t2.p1
and t3.p2>t2.p2
and pkg_prim2.isprim(t2.p2||t3.p2)=0 and pkg_prim2.isprim(t3.p2||t2.p2)=0)
, t4 as (select t3.p1 p1, t3.p2 p2, t3.p3, t4.p3 p4 from t3, t3 t4
where t4.p1=t3.p1 and t4.p2 = t3.p2
and t4.p3>t3.p3
and pkg_prim2.isprim(t3.p3||t4.p3)=0 and pkg_prim2.isprim(t4.p3||t3.p3)=0)
, t5 as (select t4.p1 p1, t4.p2 p2, t4.p3, t4.p4 p4, t5.p4 p5 from t4, t4 t5
where t5.p1=t4.p1 and t5.p2 = t4.p2 and t5.p3=t4.p3
and t5.p4>t4.p4
and pkg_prim2.isprim(t4.p4||t5.p4)=0 and pkg_prim2.isprim(t5.p4||t4.p4)=0)
select p1,p2,p3,p4,p5, p1+p2+p3+p4+p5 total from t5
P1 P2 P3 P4 P5 TOTAL
---------- ---------- ---------- ---------- ---------- ----------
13 5197 5701 6733 8389 26033
Executed in 345.438 seconds
一点都不花哨, 从t3开始,后面的几乎就是前面简单的重复。
尽管仍然要近7分钟, 但比起之前的代码性能好多了。 |
|