|
使用了subtype,并将原本int型的变量定义成了varchar型, 故而
f := least(0, c(40), c(41));
z(least(f, c(39)));
z(c(39), 0);
z(f, 30, 1);
这段代码中的
z(least(f, c(39)));
这一行有BUG,还得加上一个常数0.
既然f,g都定义成 w (varchar)型了,故而可以复用 s,x这两个变量.
从而又可以减少6个字节,但是修正上面的BUG需多两个字节,故此次修改可以减少4个字节.
PS: 帖子内容能追加折叠功能吗?不想代码默认的显示出来占大量空间.
长度变为: 1211 byte
create or replace package easter is
procedure showAllEasterDay;
procedure showMaxOccurenceEasterDay;
procedure showLeapEasterDay;
procedure showFoolEasterDay;
end;
/
create or replace package body easter is
c dbms_sql.varchar2s;
subtype w is varchar(999);
s w;
x w;
v date := date '1-3-31';
procedure p(t w) is
begin
dbms_output.put_line(t);
for i in -30 .. 50 loop
c(i) := 0;
end loop;
for y in 2011 .. 2099 loop
x := y - 1900;
s := x mod 19;
s := (11 * s + 4 - trunc((7 * s + 1) / 19)) mod 29;
x := 25 - s - (x + trunc(x / 4) + 31 - s) mod 7;
c(y) := to_char(v + x, ' mm-dd');
c(x) := c(x) - 1;
s := sign(x - 1) + 40;
c(s) := least(0, c(x), c(s));
end loop;
s := '';
end;
procedure showAllEasterDay is
begin
p('YEAR DAY');
for y in 2011 .. 2099 loop
p(y || c(y));
end loop;
end;
procedure z(w w, n w := 30, m w := -30) is
begin
for f in m .. n loop
if c(f) = w then
s := s || to_char(v + f, 'mm-dd/');
end if;
end loop;
s := rtrim(s, '/') || ' ' || -w || ' ';
end;
procedure showMaxOccurenceEasterDay is
begin
p('MAXOCC MO_CNT MAXOCC_3 MO3_CNT MAXOCC_4 MO4_CNT');
x := least(0, c(40), c(41));
z(least(0, x, c(39)));
z(c(39), 0);
z(x, 30, 1);
p(s);
end;
procedure showLeapEasterDay is
begin
p('ABSENT_START ABSENT_END');
for i in 22 - 31 .. 25 loop
x := to_char(v + i, 'mm-dd ');
if c(i) = 0 then
s := nvl(s, x);
end if;
if s < x and (i = 25 or c(i + 1) < 0) then
p(s || x);
end if;
end loop;
end;
procedure showFoolEasterDay is
begin
p('YEAR TOTAL');
for y in 2011 .. 2099 loop
if substr(c(y), -2) = 1 then
p(y || ' ' || -c(40));
end if;
end loop;
end;
end;
/ |
|