查看: 75719|回复: 437

[精华] 最小源代码擂台

[复制链接]
论坛徽章:
69
生肖徽章2007版:羊
日期:2008-11-14 14:42:19复活蛋
日期:2011-08-06 08:59:05ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主4段
日期:2012-05-15 15:24:11
跳转到指定楼层
1#
发表于 2008-4-24 10:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
此擂台赛已经结束, 尚未整理, 先把奖励送出.
DragonBill:           344 Bytes 第一名攻擂成功!奖励2000PUB$
sdxiong:              349 Bytes 第二名攻擂成功!奖励1500PUB$
junsansi:             405 Bytes 第三名奖励200PUB$
yangtingkun:       412 Bytes 参与奖励100PUB$
hotiice:                510 Bytes 参与奖励100PUB$
谁:                        583 Bytes 参与奖励100PUB$
dhl2001:              636 Bytes 参与奖励100PUB$
jiqing1004:          720 Bytes 参与奖励100PUB$
xiaochuan1206:  723 Bytes 参与奖励100PUB$
leniz:                   740 Bytes 参与奖励100PUB$

前两天在网上看到有混乱代码比赛, 心血来潮,我也来搞一个题目供娱乐娱乐.

为更多的人参与进来, 现决定以PUB币作为奖励
第一名:奖励1000PUB币, 第二名奖励500PUB币, 第三名奖励200PUB币
另攻擂成功者, 前三名额外增加1000PUB币

本次摆擂持续时间为一个月, 字节数 <= 384 即告攻擂成功.
摆擂者无论是否有更好的成绩出来, 一律以 384 字节为准作为攻擂标准.

目前设擂者成绩:  348 Bytes.

因为要更多的人参与进来,所以摆擂时间会更长一些, 请耐心等待

最新战绩一览(截止至 # 308 )
DragonBill:           344 Bytes 攻擂成功!
sdxiong:              349 Bytes 攻擂成功!
junsansi:             405 Bytes
yangtingkun:       412 Bytes
hotiice:                510 Bytes
谁:                        583 Bytes
dhl2001:              636 Bytes
jiqing1004:          720 Bytes
xiaochuan1206:  723 Bytes
leniz:                   740 Bytes


题目: 请模拟出 Oracle 中 Add_Months 函数功能的一个自定义函数.
要求:
1. 函数申明固定为:
create or replace function my_add_months(p_date_string varchar2,
                                         p_months      number)
  return varchar2
  不允许更改.

2. 代码中禁止申明日期类型的变量, 禁止使用一切与日期有关的类型转换及函数,禁止使用Oracle提供的Package, 只能使用 Oracle 的标准函数


3. 不求代码的效率高效, 但也不能太低.

4. 使用你可以使用的一切手段, 将源代码缩短, 不考虑编译后的代码长度, 这里只要求源代码最短.

5. 代码的长度以扣除其中的空白(空格, 回车换行, TAB键)后的字节长度.

6. 传入的日期字符串格式为 yyyymmdd, 增加的月份数传入整数,  函数内部你不需要检核传入的日期字符串是否有效(一定传入有效的), 月份数也不用考虑带小数的情况, 返回的日期字符串格式依然为 yyyymmdd

7. 写完函数后, 请用以下代码进行测试, 希望运行时间不要太长哦.

8. 只把测试结果贴出来, 函数代码先不贴.

9. 运算结果日期年不会超过9999, 也不会小于1600.
http://www.itpub.net/thread-977394-1-1.html 中提到1582年前使用的是凯撒时期制定的儒略历,4年一闰,
这个属历史问题, 我们这里不考虑.

10. 函数代码中禁止使用SQL语句.

待收集到一定数量的测试结果后, 再请大家贴出自己的函数源码.


测试代码:重新设计了一下测试代码, 把测试量减少一个数量级,以便更快得到结果
脚本: test.sql (2.46 KB, 下载次数: 132)
set serverout on

declare
  ln  number;
  ld  date;
  ls1 varchar2(8);
  ls2 varchar2(8);
  lt  number := dbms_utility.get_time;
  ex exception;
  y number;
  m number;
  d number;
  j number;
begin
  for j in 0 .. 5000 loop
    for y in 2000 .. 2001 loop
      for m in 2 .. 4 loop
        for d in 28 .. 31 loop
          begin
            ls1 := y || '0' || m || d;
            begin
              ld  := to_date(ls1, 'yyyymmdd');
            exception
              when others then
                exit;
            end;
            ld  := add_months(ld, j);
            ls2 := to_char(ld, 'yyyymmdd');
            if nvl(my_add_months(ls1, j), '*') <> ls2 then
              dbms_output.put_line('Sorry: stop at p_date_string=' || ls1 ||
                                   ',p_months=' || j);
              dbms_output.put_line('my_add_months returned: ' ||
                                   my_add_months(ls1, j));
              dbms_output.put_line('add_months returned: ' || ls2);
              raise ex;
            end if;
         
            ls1 := to_char(add_months(ld, -j), 'yyyymmdd');
            if nvl(my_add_months(ls2, -j), '*') <> ls1 then
              dbms_output.put_line('Sorry: stop at p_date_string=' || ls2 ||
                                   ',p_months=' || -j);
              dbms_output.put_line('my_add_months returned: ' ||
                                   my_add_months(ls2, -j));
              dbms_output.put_line('add_months returned: ' || ls1);
              raise ex;
            end if;
          exception
            when ex then
              raise;
            when others then
              raise;
          end;
        end loop;
      end loop;
    end loop;
  end loop;
  ln := 0;
  for c in (select text
              from user_source
             where name = 'MY_ADD_MONTHS'
               and type = 'FUNCTION') loop
    ln := ln + nvl(lengthb(translate(c.text,
                                     '*' || chr(9) || chr(10) || chr(13) ||
                                     chr(32),
                                     '*')),
                   0);
  end loop;
  lt := (dbms_utility.get_time - lt) / 100;
  dbms_output.put_line('Congratulation ... Code Length: ' || ln ||
                       ' Bytes. Times: ' ||
                       to_char(to_date(to_char(lt, 'fm00000'), 'sssss'),
                               'hh24:mi:ss'));
exception
  when ex then
    null;
end;
/

[ 本帖最后由 nyfor 于 2008-6-5 11:48 编辑 ]
论坛徽章:
281
2015年新春福章
日期:2015-03-06 11:57:312012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-01-04 11:51:22蛋疼蛋
日期:2011-12-29 07:37:22迷宫蛋
日期:2011-12-26 14:19:41茶鸡蛋
日期:2011-11-17 09:20:52茶鸡蛋
日期:2011-11-10 22:42:38ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15茶鸡蛋
日期:2011-10-24 09:48:48ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47
2#
发表于 2008-4-24 10:53 | 只看该作者
先留名

使用道具 举报

回复
论坛徽章:
69
生肖徽章2007版:羊
日期:2008-11-14 14:42:19复活蛋
日期:2011-08-06 08:59:05ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主4段
日期:2012-05-15 15:24:11
3#
 楼主| 发表于 2008-4-24 10:59 | 只看该作者
追加两条说明:
(1). 运算结果日期年不会超过9999, 也不会小于1600.
http://www.itpub.net/thread-977394-1-1.html 中提到1582年前使用的是凯撒时期制定的儒略历,4年一闰,
这个属历史问题, 我们这里不考虑.

(2). 函数代码中禁止使用SQL语句.

[ 本帖最后由 nyfor 于 2008-4-28 17:06 编辑 ]

使用道具 举报

回复
论坛徽章:
126
ITPUB元老
日期:2007-07-04 17:27:50会员2007贡献徽章
日期:2007-09-26 18:42:10现任管理团队成员
日期:2011-05-07 01:45:08优秀写手
日期:2015-01-09 06:00:14版主7段
日期:2015-07-16 02:10:00
4#
发表于 2008-4-24 11:05 | 只看该作者
这些问题最好的解决对象是精通C/C++、数据结构和数学高手!
本人不行!

使用道具 举报

回复
论坛徽章:
69
生肖徽章2007版:羊
日期:2008-11-14 14:42:19复活蛋
日期:2011-08-06 08:59:05ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主4段
日期:2012-05-15 15:24:11
5#
 楼主| 发表于 2008-4-24 11:55 | 只看该作者
刚发现Oracle对于1000年的02月29日好像不报错呢.
SQL> select to_date('10000229','yyyymmdd') from dual;

TO_DATE('10000229','YYYYMMDD')
------------------------------
0/0/0000

SQL> select to_char(to_date('10000229','yyyymmdd'),'yyyymmdd') from dual;

TO_CHAR(TO_DATE('10000229','YY
------------------------------
10000229

实际上1000年不是闰年啊?

Oracle 怎么回事呢?
搞得我刚刚的代码测试不通过.

更换一下测试中传入的日期以及计算后的结果日期的年份都在2000年前后来测试好了.

使用道具 举报

回复
论坛徽章:
281
2015年新春福章
日期:2015-03-06 11:57:312012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-01-04 11:51:22蛋疼蛋
日期:2011-12-29 07:37:22迷宫蛋
日期:2011-12-26 14:19:41茶鸡蛋
日期:2011-11-17 09:20:52茶鸡蛋
日期:2011-11-10 22:42:38ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15茶鸡蛋
日期:2011-10-24 09:48:48ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47
6#
发表于 2008-4-24 14:23 | 只看该作者
比想象的困难一些,黑黑`~~~~

正在调试中~

使用道具 举报

回复
论坛徽章:
281
2015年新春福章
日期:2015-03-06 11:57:312012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-01-04 11:51:22蛋疼蛋
日期:2011-12-29 07:37:22迷宫蛋
日期:2011-12-26 14:19:41茶鸡蛋
日期:2011-11-17 09:20:52茶鸡蛋
日期:2011-11-10 22:42:38ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15茶鸡蛋
日期:2011-10-24 09:48:48ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47
7#
发表于 2008-4-24 14:24 | 只看该作者
ny大哥有没有显式指定类型转换?还是由oracle自行隐式转换数据类型?

使用道具 举报

回复
论坛徽章:
87
2015年新春福章
日期:2015-03-06 11:58:182010广州亚运会纪念徽章:轮滑
日期:2010-09-23 17:19:212010年世界杯参赛球队:乌拉圭
日期:2010-07-14 17:54:242010年世界杯参赛球队:美国
日期:2010-06-30 13:13:582010年世界杯参赛球队:墨西哥
日期:2010-06-25 12:49:452010年世界杯参赛球队:墨西哥
日期:2010-04-05 10:23:502010新春纪念徽章
日期:2010-03-01 11:06:232010新春纪念徽章
日期:2010-01-04 08:33:08生肖徽章2007版:龙
日期:2009-11-12 16:31:13参与WIN7挑战赛纪念
日期:2009-11-09 11:50:09
8#
发表于 2008-4-24 14:32 | 只看该作者
關注!

使用道具 举报

回复
论坛徽章:
69
生肖徽章2007版:羊
日期:2008-11-14 14:42:19复活蛋
日期:2011-08-06 08:59:05ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主4段
日期:2012-05-15 15:24:11
9#
 楼主| 发表于 2008-4-24 14:33 | 只看该作者
不需要显示指定类型转换. 可全部使用隐式转换.
这是其中的一种缩减源代码长度的一种手段

使用道具 举报

回复
论坛徽章:
69
生肖徽章2007版:羊
日期:2008-11-14 14:42:19复活蛋
日期:2011-08-06 08:59:05ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主4段
日期:2012-05-15 15:24:11
10#
 楼主| 发表于 2008-4-24 15:07 | 只看该作者
重新设计了一下测试代码, 把测试量减少一个数量级,以便更快得到测试结果

使用道具 举报

回复

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

本版积分规则 发表回复

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