chyanog 发表于 2010-9-8 17:08:40

8# Frankenstein
Mathematica编程可选风格中函数式写法更简洁,本身又自带大量函数,很多时候代码可以写的很精简。相比之下,其实J语言(http://www.jsoftware.com/)更为简洁,可谓异常简洁!求解代码如下,可惜我最近没时间学。
I.(=+/@(!@"."0@":)"0)i.1e5

wayne 发表于 2010-9-9 10:33:21

11# chyanog
J语言的确非常之简洁,不过,与此同时,其可读性也是非常之差的。

即便是J语言的编程人员,还得动不动去查看手册,查阅 函数对应的符号,麻烦。

chyanog 发表于 2010-9-13 22:47:41

我把阶乘改成双阶乘,发现这样的数也不多,也是4个,物以稀为贵嘛。到在线序列百科上验证了一下,的确如此
(http://www.research.att.com/~njas/sequences/?q=1%2C2%2C3%2C107&sort=0&fmt=0&language=english)。
My Mathematica Code:
Module[{N, n},
N = n /. {ToRules@Reduce} // Max;
Do[
   If!!] == i,
    Print]
   , {i, 10^(N + 1)}]
] // Timing
1
2
3
107

有些奇怪的是Mathematica中,更专业的数组求和函数"Total"往往不如"Tr"效率高,也不如"Plus@@"。

wayne 发表于 2010-9-20 13:15:19

13# chyanog
没这个理吧:

mathe 发表于 2010-9-20 16:07:22

16进制结果好像有
1=1!
2=2!
260f3b66bf9=2!+6!+0!+f!+3!+b!+6!+6!+b!+f!+9!

chyanog 发表于 2010-9-20 22:52:31

14# wayne
这个我也不清楚了,你的测试没有问题。不过我13楼的代码把Tr换为Total的话,速度是稍有下降的,你可以多试几次。

chyanog 发表于 2010-9-20 23:13:50

mathe的结果不错!
我顺藤摸瓜找到了相关链接有,上面统计的比较全面,包括了各种进制。
http://en.wikipedia.org/wiki/Factorion

wayne 发表于 2010-9-21 11:51:07

16# chyanog
仅根据你的代码的那么一丁点差距,就断定Tr逊于 Total,我感觉是不妥的。
1、Mathematica是模块化的函数式的语言,不同于C语言那种命令式的,这就意味着,同样的命令在不同的语句环境下执行效率有可能是不一样的。
2、存在即合理。Total的操作对象是线性表,List,Tr的操作对象是矩阵,List的List ,我感觉二者还是各自擅长各自的领域。

chyanog 发表于 2010-9-21 14:41:15

18# wayne
分析的不错,打错了吧:lol ,我说的是Tr胜于Total。之所以这么说是因为有好几次用Tr效率都不在Total之下,而且Tr更短,功能上几乎可以完全取代Total,我便有些偏爱它了。
      另外现在注意到Mathematica的确有些慢,尽管用函数式编程,如果用For(或While)的话速度就更慢了,Do或Select或Cases等速度相对还算可以接受。不少人往往抱怨Java慢,最近通过几个小测试我发现和C的运行时间差不多都是一个数量级的,个别时候甚至胜过C(当然与编译器优化有关)。

mathe 发表于 2010-9-21 16:55:44

给个代码,重新定义宏B就可以得到不同进制的结果。
但是B太大可能long long的数据要溢出。
另外,对于比较大的B可能速度会有点慢,如果能够在搜索过程中添加一些剪枝措施应该会快很多#include <stdio.h>
#ifndef B
#define B 16
#endif
#define MAXDIGITS 100
long long facs;
long long dsum;
int counts;
long long cursum;
long long lowerbound;
int maxH;
void init()
{
    int i;
    facs=1LL;
    dsum=1LL;
    for(i=1;i<B;i++){
      facs=facs*i;
      dsum=dsum*B;
    }
}

int find_max_digits()
{
    long long d=facs;
    long long Bh=1LL;
    int h;
    for(h=2;;h++){
      d+=facs;Bh*=B;
      if(d<Bh)return h-1;
    }
}

void checkresult()
{
    int lcount;
    char dstr;
    int i,first=1;
    for(i=0;i<B;i++)lcount=0;
    long long u=cursum;
    int len=0;
    if(cursum==0)return;
    while(u>0){
      lcount++;
      u/=B;
      len++;
    }
    for(i=0;i<B;i++)if(lcount!=counts)return;
    u=cursum;
    dstr='\0';
    while(u>0){
      len--;
      char d=u%B;
      if(d<=9)d+='0';
      else d+='A'-10;
      dstr=d;
      u/=B;
    }
    printf("%s=",dstr);
    for(i=0;i<dstr!='\0';i++){
         if(i>0)printf("+");
         printf("%c!",dstr);
    }
    printf("\n");
}

void searchfor(int digit, int leftcount)
{
    int i,j;
    long long nsum;
    if(leftcount==0||digit<0){
       checkresult();
       return;
    }
    for(i=leftcount;i>=0;i--){
      counts=i;
      cursum+=facs*i;
      searchfor(digit-1,leftcount-i);
      cursum-=facs*i;
    }
}

void searchdigits(int digits)
{
    int i;
    for(i=0;i<B;i++)counts=0;
    cursum=0LL;
    lowerbound=0LL;
    searchfor(B-1,digits);
}

int main()
{
    int h;
    init();
    maxH=find_max_digits();
    if(maxH>=MAXDIGITS){
      fprintf(stderr,"Too large digits\n");
      return -1;
    }
    searchdigits(maxH);
}
页: 1 [2]
查看完整版本: 回归数续集---自阶乘