楼主: tree_new_bee

Euler Project 挨个做 - 之一(Q1-50)

[复制链接]
论坛徽章:
10
CTO参与奖
日期:2009-02-20 09:44:20ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30迷宫蛋
日期:2012-05-07 10:55:58茶鸡蛋
日期:2012-04-19 16:08:262012新春纪念徽章
日期:2012-01-04 11:54:462011新春纪念徽章
日期:2011-01-04 10:24:02数据库板块每日发贴之星
日期:2010-12-19 01:01:02数据库板块每日发贴之星
日期:2010-12-13 01:01:012009日食纪念
日期:2009-07-22 09:30:00优秀写手
日期:2014-02-08 06:00:12
81#
 楼主| 发表于 2010-12-16 19:22 | 只看该作者
16. What is the sum of the digits of the number 2^1000?

这个问题在帖子: 求2^1000的各位数字之和 里,已经讨论的很充分了。 不再详细讨论。

用递归with计算大数相乘,在http://www.itpub.net/viewthread. ... ;page=1#pid16957717里已经有了。

这里只贴出我的大数相乘的PLSQL,并把相应的幂和阶乘运算放到一个Package中。
这里用得到幂, 后面的题目会用到阶乘。

create or replace package body pkg_bignum is

  function bigmulti(d1 varchar2, d2 varchar2) return varchar2 is
    Result varchar2(4000) := '';
    type t_numlist is table of number index by PLS_INTEGER;
    numlist t_numlist;
    i       number;
    j       number;
    lastm   number;
    tmp     number;
  begin
  
    for i in 1 .. length(d1) + length(d2) loop
      numlist(i) := 0;
    end loop;
  
    for i in 1 .. length(d1) loop
      for j in 1 .. length(d2) loop
        numlist(i + j - 1) := numlist(i + j - 1) +
                              substr(d1, -i, 1) * substr(d2, -j, 1);
      end loop;
    end loop;
  
    lastm := 0;
    for i in 1 .. length(d1) + length(d2) loop
      tmp := mod(numlist(i) + lastm, 10);
      lastm := trunc((numlist(i) + lastm) / 10);
      numlist(i) := tmp;
      result := numlist(i) || result;
    end loop;
  
    return(ltrim(Result, '0'));
  end;

  function bigpower(d1 varchar2, n number) return varchar2 is
    result varchar2(4000);
  begin
    result := '1';
    for i in 1 .. n loop
      result := bigmulti(result, d1);
    end loop;
    return result;
  end;

  function bigfact(d1 varchar2) return varchar2 is
    result varchar2(4000);
  begin
    result := '1';
    for i in 2 .. d1 loop
      result := bigmulti(result, i);
    end loop;
    return result;
  end;

end pkg_bignum;



测试,无论(2, 1000),  (2^10, 100) 还是(2^100, 10)都很快。
SQL> with t as (select /*+ RESULT_CACHE  */ pkg_bignum.bigpower(power(2, 100), 10) str from dual)
  2  ,t1 as (select rownum n from T connect by rownum<= length(str))
  3  select  sum(substr(str,n,1)) from t, t1;

SUM(SUBSTR(STR,N,1))
--------------------
                1366

Executed in 0.079 seconds
SQL> with t as (select /*+ RESULT_CACHE  */ pkg_bignum.bigpower(power(2, 10), 100) str from dual)
  2  ,t1 as (select rownum n from T connect by rownum<= length(str))
  3  select  sum(substr(str,n,1)) from t, t1;

SUM(SUBSTR(STR,N,1))
--------------------
                1366

Executed in 0.031 seconds
SQL> with t as (select /*+ RESULT_CACHE  */ pkg_bignum.bigpower( 2, 1000) str from dual)
  2  ,t1 as (select rownum n from T connect by rownum<= length(str))
  3  select  sum(substr(str,n,1)) from t, t1;

SUM(SUBSTR(STR,N,1))
--------------------
                1366

Executed in 0.016 seconds

SQL>

使用道具 举报

回复
论坛徽章:
10
CTO参与奖
日期:2009-02-20 09:44:20ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30迷宫蛋
日期:2012-05-07 10:55:58茶鸡蛋
日期:2012-04-19 16:08:262012新春纪念徽章
日期:2012-01-04 11:54:462011新春纪念徽章
日期:2011-01-04 10:24:02数据库板块每日发贴之星
日期:2010-12-19 01:01:02数据库板块每日发贴之星
日期:2010-12-13 01:01:012009日食纪念
日期:2009-07-22 09:30:00优秀写手
日期:2014-02-08 06:00:12
82#
 楼主| 发表于 2010-12-16 20:10 | 只看该作者
Q17: How many letters would be needed to write all the numbers in words from 1 to 1000?

If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.

If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?


这个没难度, 纯粹是体力活,也是细心活。


with
  ta as ( select '03354435543668877988' na, '0066555766' nb from dual) -- na:0-19 nb: 00-90
, t as (select rownum num from dual connect by rownum<1000)
, t1 as (select num, 0 + case when num/100 >=1 then to_number(substr(na,num/100+1,1)) + 7 else 0 end  -- 7: hundred
+ case when num/100>=1 and mod(num,100)>0 then 3 else 0 end  -- 3: x handred and y
+ case when mod(num,100) < 20 then to_number(substr(na,mod(num,100)+1,1)) -- 0-19
       else to_number(substr(nb, mod(num,100)/10+1,1)) + to_number(substr(na,mod(num,10)+1,1)) end pron -- 20-99
         from t, ta  )
select sum(pron)+ 11 from t1  -- 11 for 1000: one thousand

SUM(PRON)+11
------------
       21124

SQL>

使用道具 举报

回复
论坛徽章:
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
83#
发表于 2010-12-16 21:27 | 只看该作者

回复 #82 tree_new_bee 的帖子

一个更oracle的写法,可惜结果好象不对
SQL> select sum(n) from(select length(trim(to_char(add_months(date'0001-1-1',12*(level-1)),'Year')))n from dual connect by level<=1000);

    SUM(N)
----------
     14483

SQL> select n from(select to_char(add_months(date'0901-1-1',12*(level-1)),'Year')n from dual connect by level<=1000)where rownum<=20;

N
------------------------------------------
Nine Hundred One
Nine Hundred Two
Nine Hundred Three
Nine Hundred Four
Nine Hundred Five
Nine Hundred Six
Nine Hundred Seven
Nine Hundred Eight
Nine Hundred Nine
Nine Ten
Nine Eleven
Nine Twelve
Nine Thirteen
Nine Fourteen
Nine Fifteen
Nine Sixteen
Nine Seventeen
Nine Eighteen
Nine Nineteen
Nine Twenty

使用道具 举报

回复
论坛徽章:
10
CTO参与奖
日期:2009-02-20 09:44:20ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30迷宫蛋
日期:2012-05-07 10:55:58茶鸡蛋
日期:2012-04-19 16:08:262012新春纪念徽章
日期:2012-01-04 11:54:462011新春纪念徽章
日期:2011-01-04 10:24:02数据库板块每日发贴之星
日期:2010-12-19 01:01:02数据库板块每日发贴之星
日期:2010-12-13 01:01:012009日食纪念
日期:2009-07-22 09:30:00优秀写手
日期:2014-02-08 06:00:12
84#
 楼主| 发表于 2010-12-16 21:30 | 只看该作者
原帖由 〇〇 于 2010-12-16 21:27 发表
一个更oracle的写法,可惜结果好象不对
SQL> select sum(n) from(select length(trim(to_char(add_months(date'0001-1-1',12*(level-1)),'Year')))n from dual connect by level select n from(select to_char(add_months(date'0901-1-1',12*(level-1)),'Year')n from dual connect by level


看你的结果的第一行就知道不对。
901 读作 nine hundred and one,  对year的to_char漏了and了。

不过用日期这个主意不错。

[ 本帖最后由 tree_new_bee 于 2010-12-16 21:39 编辑 ]

使用道具 举报

回复
论坛徽章:
15
2010广州亚运会纪念徽章:游泳
日期:2010-11-12 16:42:09ITPUB社区12周年站庆徽章
日期:2013-10-08 14:53:15奥迪
日期:2013-08-21 15:24:502013年新春福章
日期:2013-02-25 14:51:24双黄蛋
日期:2012-11-14 15:31:42ITPUB 11周年纪念徽章
日期:2012-10-09 18:16:00ITPUB 11周年纪念徽章
日期:2012-09-28 17:34:42奥运会纪念徽章:艺术体操
日期:2012-08-08 20:15:19奥运会纪念徽章:乒乓球
日期:2012-08-06 16:51:01蛋疼蛋
日期:2012-03-28 09:35:54
85#
发表于 2010-12-16 21:57 | 只看该作者
学习

使用道具 举报

回复
论坛徽章:
10
CTO参与奖
日期:2009-02-20 09:44:20ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30迷宫蛋
日期:2012-05-07 10:55:58茶鸡蛋
日期:2012-04-19 16:08:262012新春纪念徽章
日期:2012-01-04 11:54:462011新春纪念徽章
日期:2011-01-04 10:24:02数据库板块每日发贴之星
日期:2010-12-19 01:01:02数据库板块每日发贴之星
日期:2010-12-13 01:01:012009日食纪念
日期:2009-07-22 09:30:00优秀写手
日期:2014-02-08 06:00:12
86#
 楼主| 发表于 2010-12-16 22:01 | 只看该作者
想在你那个上面加工加工, 可是好像不止那一个地方, 对年份的拼写,很多地方都与普通的读法不同。

比如:
609        609        Six Hundred Nine
610        610        Six Ten
就是当后面的不是单位数时, 就分两节读, 不再加hundred了。
hundred 加个and好加, 这个Six Ten不好处理。

使用道具 举报

回复
论坛徽章:
10
CTO参与奖
日期:2009-02-20 09:44:20ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30迷宫蛋
日期:2012-05-07 10:55:58茶鸡蛋
日期:2012-04-19 16:08:262012新春纪念徽章
日期:2012-01-04 11:54:462011新春纪念徽章
日期:2011-01-04 10:24:02数据库板块每日发贴之星
日期:2010-12-19 01:01:02数据库板块每日发贴之星
日期:2010-12-13 01:01:012009日食纪念
日期:2009-07-22 09:30:00优秀写手
日期:2014-02-08 06:00:12
87#
 楼主| 发表于 2010-12-16 22:24 | 只看该作者
土洋结合, 百位前用我的笨办法,十位以内的数字用你的办法取。 这样除了Hundred和thousande这两个词外,省了硬编码其它数字了。

with ta as  (select level d, replace(to_char(add_months(date'0001-1-1',12*(level-1)),'Year'),'-', ' ') str from dual connect by rownum<=99)
, t as (select rownum num from dual connect by rownum<1000)
, t1 as (select num, case when num/100 >=1 then (select str || ' Hundred ' from ta where d=floor(num/100))  else ' ' end  -- 7: hundred
  || case when num/100>=1 and mod(num,100)>0 then ' AND ' else '' end  -- 3: x handred and y
  || (select str  from ta where d=mod(num,100)) pron
           from t )
select sum(length(replace(pron,' ', '')))+11 from t1  

SUM(LENGTH(REPLACE(PRON,'','')
------------------------------
                         21124

SQL>

[ 本帖最后由 tree_new_bee 于 2010-12-16 22:28 编辑 ]

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期: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
88#
发表于 2010-12-16 22:28 | 只看该作者
这个也是没有AND的:
SELECT  to_char(to_timestamp(LPAD(LEVEL,9,'0'),'FF9'),'FFSP') FROM DUAL WHERE LEVEL>980 CONNECT BY LEVEL<=1000;

TO_CHAR(TO_TIMESTAMP(LPAD(LEVEL,9,'0'),'FF9'),'FFSP')
----------------------------------------------------------------------
NINE HUNDRED EIGHTY-ONE
NINE HUNDRED EIGHTY-TWO
NINE HUNDRED EIGHTY-THREE
NINE HUNDRED EIGHTY-FOUR
NINE HUNDRED EIGHTY-FIVE
NINE HUNDRED EIGHTY-SIX
NINE HUNDRED EIGHTY-SEVEN
NINE HUNDRED EIGHTY-EIGHT
NINE HUNDRED EIGHTY-NINE
NINE HUNDRED NINETY
NINE HUNDRED NINETY-ONE
NINE HUNDRED NINETY-TWO
NINE HUNDRED NINETY-THREE
NINE HUNDRED NINETY-FOUR
NINE HUNDRED NINETY-FIVE
NINE HUNDRED NINETY-SIX
NINE HUNDRED NINETY-SEVEN
NINE HUNDRED NINETY-EIGHT
NINE HUNDRED NINETY-NINE
ONE THOUSAND

使用道具 举报

回复
论坛徽章:
10
CTO参与奖
日期:2009-02-20 09:44:20ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30迷宫蛋
日期:2012-05-07 10:55:58茶鸡蛋
日期:2012-04-19 16:08:262012新春纪念徽章
日期:2012-01-04 11:54:462011新春纪念徽章
日期:2011-01-04 10:24:02数据库板块每日发贴之星
日期:2010-12-19 01:01:02数据库板块每日发贴之星
日期:2010-12-13 01:01:012009日食纪念
日期:2009-07-22 09:30:00优秀写手
日期:2014-02-08 06:00:12
89#
 楼主| 发表于 2010-12-16 22:38 | 只看该作者
上面这个容易加工一点, 只要用like '%HUNDRED__% 替换为HUNDRED AND即可。

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期: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
90#
发表于 2010-12-16 23:35 | 只看该作者
那个走方格的题目,我以前在这里见过,费了半天劲才搜索出来:
http://www.itpub.net/viewthread. ... p;extra=&page=1

使用道具 举报

回复

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

本版积分规则 发表回复

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