找回密码
 欢迎注册
楼主: wayne

[讨论] 回归数续集---自阶乘

[复制链接]
发表于 2010-9-8 17:08:40 | 显示全部楼层
8# Frankenstein
Mathematica编程可选风格中函数式写法更简洁,本身又自带大量函数,很多时候代码可以写的很精简。相比之下,其实J语言(http://www.jsoftware.com/)更为简洁,可谓异常简洁!求解代码如下,可惜我最近没时间学。

  1. I.(=+/@(!@"."0@":)"0)i.1e5
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-9-9 10:33:21 | 显示全部楼层
11# chyanog
J语言的确非常之简洁,不过,与此同时,其可读性也是非常之差的。

即便是J语言的编程人员,还得动不动去查看手册,查阅 函数对应的符号,麻烦。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-9-13 22:47:41 | 显示全部楼层
我把阶乘改成双阶乘,发现这样的数也不多,也是4个,物以稀为贵嘛。到在线序列百科上验证了一下,的确如此
http://www.research.att.com/~nja ... mp;language=english)。
My Mathematica Code:

  1. Module[{N, n},
  2.   N = n /. {ToRules@Reduce[9!!*n > 10^n, n, Integers]} // Max;
  3.   Do[
  4.    If[Tr[IntegerDigits[i]!!] == i,
  5.     Print[i]]
  6.    , {i, 10^(N + 1)}]
  7.   ] // Timing
复制代码
1
2
3
107

有些奇怪的是Mathematica中,更专业的数组求和函数"Total"往往不如"Tr"效率高,也不如"Plus@@"。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-9-20 13:15:19 | 显示全部楼层
13# chyanog
没这个理吧:

ddd.png
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-9-20 16:07:22 | 显示全部楼层
16进制结果好像有
1=1!
2=2!
260f3b66bf9=2!+6!+0!+f!+3!+b!+6!+6!+b!+f!+9!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-9-20 22:52:31 | 显示全部楼层
14# wayne
这个我也不清楚了,你的测试没有问题。不过我13楼的代码把Tr换为Total的话,速度是稍有下降的,你可以多试几次。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-9-20 23:13:50 | 显示全部楼层
mathe的结果不错!
我顺藤摸瓜找到了相关链接有,上面统计的比较全面,包括了各种进制。
http://en.wikipedia.org/wiki/Factorion

评分

参与人数 1贡献 +3 收起 理由
gxqcn + 3 链接有参考价值

查看全部评分

毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-9-21 11:51:07 | 显示全部楼层
16# chyanog
仅根据你的代码的那么一丁点差距,就断定Tr逊于 Total,我感觉是不妥的。
1、Mathematica是模块化的函数式的语言,不同于C语言那种命令式的,这就意味着,同样的命令在不同的语句环境下执行效率有可能是不一样的。
2、存在即合理。Total的操作对象是线性表,List,Tr的操作对象是矩阵,List的List ,我感觉二者还是各自擅长各自的领域。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-9-21 14:41:15 | 显示全部楼层
18# wayne
分析的不错,打错了吧 ,我说的是Tr胜于Total。之所以这么说是因为有好几次用Tr效率都不在Total之下,而且Tr更短,功能上几乎可以完全取代Total,我便有些偏爱它了。
      另外现在注意到Mathematica的确有些慢,尽管用函数式编程,如果用For(或While)的话速度就更慢了,Do或Select或Cases等速度相对还算可以接受。不少人往往抱怨Java慢,最近通过几个小测试我发现和C的运行时间差不多都是一个数量级的,个别时候甚至胜过C(当然与编译器优化有关)。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-9-21 16:55:44 | 显示全部楼层
给个代码,重新定义宏B就可以得到不同进制的结果。
但是B太大可能long long的数据要溢出。
另外,对于比较大的B可能速度会有点慢,如果能够在搜索过程中添加一些剪枝措施应该会快很多
  1. #include <stdio.h>
  2. #ifndef B
  3. #define B 16
  4. #endif
  5. #define MAXDIGITS 100
  6. long long facs[B];
  7. long long dsum[B];
  8. int counts[B];
  9. long long cursum;
  10. long long lowerbound;
  11. int maxH;
  12. void init()
  13. {
  14.     int i;
  15.     facs[0]=1LL;
  16.     dsum[0]=1LL;
  17.     for(i=1;i<B;i++){
  18.         facs[i]=facs[i-1]*i;
  19.         dsum[i]=dsum[i-1]*B;
  20.     }
  21. }

  22. int find_max_digits()
  23. {
  24.     long long d=facs[B-1];
  25.     long long Bh=1LL;
  26.     int h;
  27.     for(h=2;;h++){
  28.       d+=facs[B-1];Bh*=B;
  29.       if(d<Bh)return h-1;
  30.     }
  31. }

  32. void checkresult()
  33. {
  34.     int lcount[B];
  35.     char dstr[MAXDIGITS];
  36.     int i,first=1;
  37.     for(i=0;i<B;i++)lcount[i]=0;
  38.     long long u=cursum;
  39.     int len=0;
  40.     if(cursum==0)return;
  41.     while(u>0){
  42.         lcount[u%B]++;
  43.         u/=B;
  44.         len++;
  45.     }
  46.     for(i=0;i<B;i++)if(lcount[i]!=counts[i])return;
  47.     u=cursum;
  48.     dstr[len]='\0';
  49.     while(u>0){
  50.         len--;
  51.         char d=u%B;
  52.         if(d<=9)d+='0';
  53.         else d+='A'-10;
  54.         dstr[len]=d;
  55.         u/=B;
  56.     }
  57.     printf("%s=",dstr);
  58.     for(i=0;i<dstr[i]!='\0';i++){
  59.          if(i>0)printf("+");
  60.          printf("%c!",dstr[i]);
  61.     }
  62.     printf("\n");
  63. }

  64. void searchfor(int digit, int leftcount)
  65. {
  66.     int i,j;
  67.     long long nsum;
  68.     if(leftcount==0||digit<0){
  69.        checkresult();
  70.        return;
  71.     }
  72.     for(i=leftcount;i>=0;i--){
  73.         counts[digit]=i;
  74.         cursum+=facs[digit]*i;
  75.         searchfor(digit-1,leftcount-i);
  76.         cursum-=facs[digit]*i;
  77.     }
  78. }

  79. void searchdigits(int digits)
  80. {
  81.     int i;
  82.     for(i=0;i<B;i++)counts[i]=0;
  83.     cursum=0LL;
  84.     lowerbound=0LL;
  85.     searchfor(B-1,digits);
  86. }

  87. int main()
  88. {
  89.     int h;
  90.     init();
  91.     maxH=find_max_digits();
  92.     if(maxH>=MAXDIGITS){
  93.       fprintf(stderr,"Too large digits\n");
  94.       return -1;
  95.     }
  96.     searchdigits(maxH);
  97. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-4-21 00:06 , Processed in 0.047369 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表