楼主: lastwinner

[精华] 2011复活节就要到了,来个最短源代码比赛吧![22日23点59分及之前提交代码都行!]

 关闭 [复制链接]
论坛徽章:
226
BLOG每日发帖之星
日期:2010-02-11 01:01:06紫蛋头
日期:2013-01-12 23:45:222013年新春福章
日期:2013-02-25 14:51:24问答徽章
日期:2013-10-17 18:06:40优秀写手
日期:2013-12-18 09:29:10马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:14
271#
发表于 2011-4-23 16:11 | 只看该作者
用了一个很取巧的办法,大约节省了10多个字节
利用TABLE()后,只有用COLUMN_VALUE来指定列的名称,而这个长度太浪费了,于是在动态SQL中被我用空格代替了,最后再用REPLACE替换回来。

最后一天实在没有时间了,直到晚上11点多才抽出时间把代码提上去。
其实如果利用这种方式,将动态SQL中一些经常出现的较长的字符串用空格或回车来替换,可以进一步减少代码量,不过这种方式属于钻评判的漏洞,如果不用空格,用一些特殊字符替换也是可以的,不过代码长度会多一点

使用道具 举报

回复
论坛徽章:
32
祖国60周年纪念徽章
日期:2009-10-09 08:28:002013年新春福章
日期:2013-02-25 14:51:24迷宫蛋
日期:2013-06-28 11:09:23ITPUB季度 技术新星
日期:2013-07-30 16:04:58优秀写手
日期:2013-12-18 09:29:132014年新春福章
日期:2014-02-18 16:43:09马上有钱
日期:2014-02-18 16:43:09红孩儿
日期:2014-03-04 16:40:38美羊羊
日期:2015-02-16 16:36:28懒羊羊
日期:2015-03-04 14:52:11
272#
发表于 2011-4-23 19:01 | 只看该作者
了解了一点新写法,在原有基础上改进了一些,开源一下。
1442:

create or replace package easter as
    procedure showAllEasterDay;
    procedure showMaxOccurenceEasterDay;
    procedure showLeapEasterDay;
    procedure showFoolEasterDay;
end;
/
create or replace package body easter as
    subtype w is varchar2(99);

    type s is table of w index by w;
    u s;
    r s;
    v s;
    t w;
    q w := 0;
    m w := 0;
    n w := 0;
   
    a w;
    b w;
    c w;
    d w;
    e w;
    f w := 1900;

    procedure p(a w)as begin dbms_output.put_line(a); end;

    procedure showAllEasterDay as
    begin
        p('YEAR    DAY');
        for i in 1 .. v.count loop
            p(v(i));
        end loop;
    end;

    procedure showMaxOccurenceEasterDay as
        d  w;
        e  w;
    begin
        a := u.first;
        while a is not null loop
            b := u(a);
            if b = q then
                d := d || '/' || a;
            end if;
            if a like '03%' and b = m then
                e := e || '/' || a;
            elsif b = n then
                f := f || '/' || a;
            end if;
            a := u.next(a);
        end loop;

        p('MAXOCC             MO_CNT  MAXOCC_3      MO3_CNT    MAXOCC_4     MO4_CNT    ');
        p(d || '  '  || q || '       ' ||
          e || '         '  || m  || '          '  ||
          f || '  '  || n);
    end;

    procedure showLeapEasterDay as
    begin
        f := 0;
        p('ABSENT_START  ABSENT_END');
        for i in 0 .. date'1-4-25' - date'1-3-22' + 1 loop
            a := to_char(date'1-3-22' + i, 'mm-dd');
            if u.exists(a) then
                if f = 1 then
                    p(b || '          ' || e);
                end if;
                f := 0;
            else
                e := a;
                if f = 0 then
                    b := a;
                end if;
                if a = '04-25' then
                    p(b || '          ' || e);
                end if;
                f := 1;
            end if;
        end loop;
    end;

    procedure showFoolEasterDay as
    begin
        p('YEAR    TOTAL');
        for i in 1 .. r.count loop
            p(r(i) || '     ' || t);
        end loop;
    end;

begin
    u.delete;
    t := 0;
    for i in f .. 2099 loop
        d := i - f;
        a := d mod 19;
        c := (11 * a + 4 - trunc((7 * a + 1)/19)) mod 29;
        b := 25-c-mod(d + trunc(d/4) + 31 - c, 7);

        if b > 0
        then a := '04'; c := b;
        else a := '03'; c := 31+b;
        end if;
        c := lpad(c,2,0);

        b := a||'-'||c;
        v(d+1) := i || '    ' || b;
        if b = '04-01' then t := t + 1; r(t) := i;  end if;
        if u.exists(b) then
            e := u(b) + 1;
            if e > q then
                q := e;
            end if;
            if b like '03%' then
                m := greatest(e,m);
            else
                n := greatest(e,n);
            end if;
        else e := 1;
        end if;
        u(b) := e;
    end loop;
end;
/

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
273#
 楼主| 发表于 2011-4-23 22:00 | 只看该作者
手机操作失误,怎么成打开了,ft

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
274#
发表于 2011-4-24 10:42 | 只看该作者
newkid的把varchar subtype 一下,number改作int

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
275#
发表于 2011-4-24 21:04 | 只看该作者
cow977的算法和我类似,都没用临时内存表

使用道具 举报

回复
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
276#
发表于 2011-4-25 22:27 | 只看该作者
用了OO的SUBTYPE以后下降为1267:

CREATE OR REPLACE PACKAGE easter
AS
PROCEDURE showAllEasterDay;
PROCEDURE showMaxOccurenceEasterDay;
PROCEDURE showLeapEasterDay;
PROCEDURE showFoolEasterDay;
END;
/
CREATE OR REPLACE PACKAGE BODY easter
AS
   SUBTYPE v IS VARCHAR(999);
   M v;
   r SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST();
   F v :='YEAR        TOTAL
';
   c v :=0;
   d DATE :=DATE '1-4-25';

PROCEDURE p(s v)
AS
BEGIN
    DBMS_OUTPUT.PUT_LINE(s);
END;

PROCEDURE showAllEasterDay
AS
BEGIN
   p('YEAR     DAY');
   FOR i IN 1..r.COUNT LOOP
       p(i+2010||'  '||r(i));
   END LOOP;
END;

FUNCTION g(i v) RETURN v
AS
   s v;
BEGIN
   select listagg(e,'/') WITHIN GROUP(ORDER BY e)||' '||MAX(c)
     INTO s
     FROM (SELECT e,RANK() OVER(ORDER BY -COUNT(*)) r,COUNT(*) c
             FROM (SELECT COLUMN_VALUE e
                     FROM TABLE(r)
                  )
            WHERE e LIKE '0'||i||'%'
          GROUP BY e
          )
   WHERE r=1;
   RETURN s||' ';
END;

PROCEDURE showMaxOccurenceEasterDay
AS
BEGIN
   p('MAXOCC   MO_CNT        MAXOCC_3   MO3_CNT              MAXOCC_4          MO4_CNT
'||g('')||g(3)||g(4));
END;

PROCEDURE showLeapEasterDay
AS
BEGIN
   p('ABSENT_START      ABSENT_END');
   FOR l IN (
   SELECT MIN(e)||'     '||MAX(e) s
     FROM (SELECT TO_CHAR(d+1-LEVEL,'MM-DD') e FROM DUAL CONNECT BY LEVEL<=34
           MINUS
           SELECT * FROM TABLE(r)
           ORDER BY 1
           )
   GROUP BY TO_DATE(e,'MM-DD')-ROWNUM
   ) LOOP
      p(l.s);
   END LOOP;
END;

PROCEDURE showFoolEasterDay
AS
BEGIN
   p(REPLACE(f,'@',C||'
'));
END;

BEGIN
   FOR N IN 111..199 LOOP
       r.EXTEND(1);
       M:=MOD(11*MOD(N,19)+4-TRUNC((7*MOD(N,19)+1)/19),29);
       M:=M+MOD(N+TRUNC(N/4)+31-M,7);
       r(n-110):=TO_CHAR(D-M,'MM-DD');
       IF M=24 THEN
          c:=c+1;
          f:=f||(1900+n)||'    @';
       END IF;
   END LOOP;
END;
/

等有空看能不能把其他技巧再加进来。

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
277#
发表于 2011-5-3 10:49 | 只看该作者
原帖由 rollingpig 于 2011-4-21 19:41 发表
非人肉保证:
1. 修改里面的2011/2099, 即可计算其他时间段数据

至于3-22和4-25,考虑到并这不是随意定的,而是正好复活节的期间,就不当成变量
4/1号也是同理,不是4/1就不存在愚蛋一说了~
其他的没办法,只能自己算

1321

这是最终的?

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
278#
 楼主| 发表于 2011-5-9 00:18 | 只看该作者
比赛结果出来了,请速去 http://www.itpub.net/thread-1425009-1-1.html 围观

使用道具 举报

回复
论坛徽章:
131
2006年度最佳技术回答
日期:2007-01-24 12:58:48福特
日期:2013-10-24 13:57:422014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上加薪
日期:2014-02-19 11:55:142013年新春福章
日期:2013-02-25 14:51:24
279#
发表于 2011-5-9 09:30 | 只看该作者
原帖由 〇〇 于 2011-5-3 10:49 发表

这是最终的?

hehe
其实我周五又精简了一些,不过,那天后来很忙,一直没更新~

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表