PLSQL算24点
很早以前就想用PLSQL写一个算24点的程序了,后来想了一下没有研究下去,最近上ITPUB的时候正好大家都在讨论,在大牛的基础上修改了一下,基本上思想和算法都是没有变的,就是学习了一下。还有两个大问题没有处理好,一是只用了枚举法,用PLSQL应该可以换个更好的递归算法的;二是没有滤重;反正最后的结果只是最简单的得到答案而已。
具体的可以参见:
create or replace function f_op (p_n1 number, p_op varchar2, p_n2 number) return number
as
begin
return case when p_op = '+' then p_n1 + p_n2
when p_op = '-' then p_n1 - p_n2
when p_op = '*' then p_n1 * p_n2
when p_op = '/' and p_n2<>0 then p_n1 / p_n2
else null
end;
end f_op;
/
create or replace procedure pro_24(p1 number, p2 number, p3 number, p4 number) as
r_result number default 0;
begin
for r in (
with t_num as
(select 1 id,p1 as n from dual
union
select 2 id,p2 as n from dual
union
select 3 id,p3 as n from dual
union
select 4 id,p4 as n from dual),
t_op as
(select '+' as o from dual
union
select '-' as o from dual
union
select '*' as o from dual
union
select '/' as o from dual)
select distinct
a.n as a,
o1.o as o1,
b.n as b,
o2.o as o2,
c.n as c,
o3.o as o3,
d.n as d
from t_num a, t_num b, t_num c, t_num d,
t_op o1, t_op o2, t_op o3
where a.id not in (b.id, c.id, d.id)
and b.id not in (c.id, d.id)
and c.id <> d.id) loop
r_result := f_op(f_op(f_op(r.a,r.o1,r.b),r.o2,r.c),r.o3,r.d);
if r_result between 23.9 and 24.1 then
dbms_output.put_line('(('||r.a||r.o1||r.b||')'||r.o2||r.c||')'||r.o3||r.d);
end if; --((a b) c) d
r_result := f_op(f_op(r.a,r.o1,f_op(r.b,r.o2,r.c)),r.o3,r.d);
if r_result between 23.9 and 24.1 then
dbms_output.put_line('('||r.a||r.o1||'('||r.b||r.o2||r.c||'))'||r.o3||r.d);
end if; --(a (b c)) d
r_result := f_op(f_op(r.a,r.o1,r.b),r.o2,f_op(r.c,r.o3,r.d));
if r_result between 23.9 and 24.1 then
dbms_output.put_line('('||r.a||r.o1||r.b||')'||r.o2||'('||r.c||r.o3||r.d||')');
end if; --(a b) (c d)
r_result := f_op(r.a,r.o1,f_op(f_op(r.b,r.o2,r.c),r.o3,r.d));
if r_result between 23.9 and 24.1 then
dbms_output.put_line(r.a||r.o1||'(('||r.b||r.o2||r.c||')'||r.o3||r.d||')');
end if; --a ((b c) d)
r_result := f_op(r.a,r.o1,f_op(r.b,r.o2,f_op(r.c,r.o3,r.d)));
if r_result between 23.9 and 24.1 then
dbms_output.put_line(r.a||r.o1||'('||r.b||r.o2||'('||r.c||r.o3||r.d||'))');
end if; --a (b (c d))
end loop;
end;
/
exec pro_24(3,3,8,8);