|
更进一步的简化是: 直接从与sqrt(10^7)最接近的数开始找, 找到第一个就返回:
declare
pl1 t_numlist;
pl2 t_numlist;
j integer;
n integer;
phi integer;
begin
pl1 := pkg_prim2.seive_numlist_nk(sqrt(1E7));
pl2 := pkg_prim2.seive_numlist_nk(1e4);
for i in reverse pl1.first .. pl1.last loop
j:= pl1.last+1;
while j<pl2.last and pl1(i)*pl2(j)< 1E7 loop
n:= pl1(i)*pl2(j);
phi := (pl1(i)-1)*(pl2(j)-1);
if TRANSLATE(n,'0123456789','0')||
TRANSLATE(n,'1023456789','1')||
TRANSLATE(n,'2013456789','2')||
TRANSLATE(n,'3012456789','3')||
TRANSLATE(n,'4012356789','4')||
TRANSLATE(n,'5012346789','5')||
TRANSLATE(n,'6012345789','6')||
TRANSLATE(n,'7012345689','7')||
TRANSLATE(n,'8012345679','8')||
TRANSLATE(n,'9012345678','9')
=
TRANSLATE(phi,'0123456789','0')||
TRANSLATE(phi,'1023456789','1')||
TRANSLATE(phi,'2013456789','2')||
TRANSLATE(phi,'3012456789','3')||
TRANSLATE(phi,'4012356789','4')||
TRANSLATE(phi,'5012346789','5')||
TRANSLATE(phi,'6012345789','6')||
TRANSLATE(phi,'7012345689','7')||
TRANSLATE(phi,'8012345679','8')||
TRANSLATE(phi,'9012345678','9')
then
dbms_output.put_line('n1:' ||pl1(i) || ' n2:' || pl2(j)|| ' n: ' || n || ' phi: ' || phi || ' n/phi:' || (n/phi));
return;
end if;
j:=j+1;
end loop;
end loop;
end;
n1:2339 n2:3557 n: 8319823 phi: 8313928 n/phi:1.00070905112481128054031740472133027854
PL/SQL procedure successfully completed
Executed in 1.047 seconds
这样快是很快, 可是有点撞大运的感觉, 虽说碰巧得到了正确答案, 但实际上循环过程中,极有可能先碰到一个i*j比较小的数符合条件。
既满足乘积最接近10^7, 又让两个数尽可能接近SQRT(10^7), 想不出什么更好的办法控制这个扩散的过程。 |
|