数学研发论坛

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

[擂台] 求形如 2^r*3^s*5^t 的整数序列

[复制链接]
发表于 2013-10-22 09:21:44 | 显示全部楼层
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2013-10-22 09:39:16 | 显示全部楼层
mathematica 发表于 2013-10-22 09:23
讨论的是别人剩下来的东西


请注意你的措词!
什么是“别人剩下来的东西”?!

首先,问题本身是个纯数学问题,不可能是什么新问题;但作为算法题,大家来PK还是很不错的(这才是关键)!
其次,发这个问题之前,我并不知道别处是否有过类似讨论,因为我是将数年前在CSDN上看到的题目再推广的。

发这个帖子的目的是为了追求极致的算法,即如何快速解决问题的过程,而非解决问题本身。
所以,何来“别人剩下来的东西”之说?

点评

"即如何快速解决问题的过程,而非解决问题本身。" 你说得有道理,至少我也学了点mathematica软件的知识  发表于 2013-10-22 14:53
我只是感叹这个讨论的问题都是别人讨论过的  发表于 2013-10-22 09:43
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-10-22 09:44:18 | 显示全部楼层
算法求解: 2^i * 3^j * 5^k i,j,k >=0. 如何用程序打印出下列的数 1 2 3 4 5 6 8 9 10 12 15 16 18 20 ..

http://zhidao.baidu.com/question/299302012

点评

里面的代码还可以进一步优化的,可以减少一些重复的乘法运算。  发表于 2013-10-22 09:52
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-10-22 14:54:17 | 显示全部楼层
  1. http://acm.fjnu.edu.cn/problem/1426
  2. #include<stdio.h>
  3. #include<iostream.h>
  4. int min(int a,int b)
  5. {
  6.         return (a>b?b:a);
  7. }
  8. int getmin(int a,int b,int c)
  9. {
  10.         return min(min(a,b),c);
  11. }
  12. void f()
  13. {
  14.         int i2,i3,i5,i,a2,a3,a5,n;
  15.         while(scanf("%d%d%d%d",&a2,&a3,&a5,&n)!=EOF)
  16.         {
  17.                 int *a=new int[n+1];
  18.                 a[0]=1;
  19.                 i2=i5=i3=0;
  20.                 for(i=1;i<=n;i++)
  21.                 {
  22.                     a[ i ]=getmin(a2*a[i2],a3*a[i3],a5*a[i5]);
  23.                     if(a[ i ]==a2*a[i2])
  24.                             i2++;
  25.                     if(a[ i ]==a3*a[i3])
  26.                             i3++;
  27.                     if(a[ i ]==a5*a[i5])
  28.                             i5++;
  29.                 }
  30.                 printf("%d\n",a[n]);
  31.                 delete a;
  32.         }
  33. }
  34. int main()
  35. {
  36.         f();
  37.         return 1;
  38. }
复制代码
我把代码复制过来,相当于备份一下
http://zhidao.baidu.com/question/299302012

点评

与我之前给出的原理基本一致; 但(a2*a[i2],a3*a[i3],a5*a[i5])这几个积可以无需多次重复计算,仅在更新时计算一次即可(需保存下来)。  发表于 2013-10-22 16:31
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-10-22 21:25:16 | 显示全部楼层


神链接。
  1. #include <iostream>
  2. #include <vector>
  3. // Hamming like sequences Generator
  4. //
  5. // Nigel Galloway. August 13th., 2012
  6. //
  7. class Ham {
  8. private:
  9.         std::vector<unsigned int> _H, _hp, _hv, _x;
  10. public:
  11.         bool operator!=(const Ham& other) const {return true;}
  12.         Ham begin() const {return *this;}
  13.         Ham end() const {return *this;}
  14.         unsigned int operator*() const {return _x.back();}
  15.         Ham(const std::vector<unsigned int> &pfs):_H(pfs),_hp(pfs.size(),0),_hv({pfs}),_x({1}){}
  16.         const Ham& operator++() {
  17.           for (int i=0; i<_H.size(); i++) for (;_hv[i]<=_x.back();_hv[i]=_x[++_hp[i]]*_H[i]);
  18.           _x.push_back(_hv[0]);
  19.           for (int i=1; i<_H.size(); i++) if (_hv[i]<_x.back()) _x.back()=_hv[i];
  20.           return *this;
  21.         }
  22. };

  23. int main() {
  24.   int count = 1;
  25.   for (unsigned int i : Ham({2,3,5})) {
  26.     if (count <= 62) std::cout << i << ' ';
  27.     if (count++ == 1691) {
  28.       std::cout << "\nThe one thousand six hundred and ninety first Hamming Number is " << i << std::endl;
  29.       break;
  30.     }
  31.   }
  32.   return 0;
  33. }


复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-10-23 02:37:33 | 显示全部楼层

Mathematica程序,不显含 if 语句。

本帖最后由 hujunhua 于 2013-10-23 16:22 编辑
  1. list={};(*预备一个空表来装要求的序列*)
  2. X={2,3,5};(*倍乘因子表*)
  3. checkb={1,1,1};(*备选框*)
  4. pointer={0,0,0};(*倍乘因子指针表,指向已得的表list中的位置*)
  5. Do[AppendTo[list,Min@checkb];(*将备选框的最小数追加到表list末*)
  6. dp=1-Sign@(checkb-Last@list);(*用1标记上一步所选最小值在备选框中的位置,其它位置标为0,作为指针的移动表*)
  7. pointer+=dp;(*按指针移动表移动指针*)
  8. checkb+=(Thread[list[[pointer]]*dp*X]-Thread[checkb*dp]),(*将有移动的指针所指的表list中的项乘以对应的倍乘因子,以所得结果按标记更新备选框*)
  9. {200}](*返回从备选框中选最小数入表的那一步,直至表长达到200*)
  10. Print[list]
复制代码
是由楼上链结中的程序改编的,效率当然也很高喽。

点评

Thread好像可以去掉?其实AppendTo在Mathematica中比较低效的  发表于 2013-10-23 17:32
其实你要是在mathematica中写一个内置函数,然后直接在notebook中调用这个函数,岂不是一行搞定?  发表于 2013-10-23 12:48
你把长的代码与短的代码都粘贴上来吧,先弄长的,再弄短的  发表于 2013-10-23 12:47
本来只3行的,按要求加了备注,显得好长,不见了MAthematica的简短  发表于 2013-10-23 12:36
能讲一下主要思路吗?我一点都看不明白  发表于 2013-10-23 09:28
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-10-23 09:29:59 | 显示全部楼层
这个,每一项必然是前面几项中某一项乘以2或者3或者5而得到的

点评

这个思路很重要  发表于 2013-10-23 09:30
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-10-23 17:10:06 | 显示全部楼层
这个题目的另一个说法是“求5-smooth数",百度知道(34#)给出的代码简单而有效,但有其局限性。用此代码求更大范围或者更大的质数的smooth数就不行了。其主要局限性是,
  1.这个算法必须从1开始求所有smooth数,而不能求某一区间的smooth数。
  2.这个算法所有求得的smooth数必须保存在内存。更大范围或者更大的质数的smooth数的个数会很多,可能导致内存不够用。不得不使用内存映射文件,或文件来存储,这会导致程序很复杂。

我正好需要计算大量的smooth数,鉴于磁盘和内存的限制,我不得不使用普通的做法,和素数的分段筛很类似,可分段求smooth数,不过求得需要的smooth数后需要排序操作,另外,我的这个算法好处是,便于分布式计算。

许多算法看上去很美,但很有局限性。和此算法一个类似的例子是《一个线性O(N)时间复杂度求素数筛法》(http://www.cnblogs.com/lzhenf/archive/2011/12/24/2300271.html),但使用后发现,虽然复杂度确实很小,但实际性能不理想,因为程序中对内存的访问局部性很差,导致cache命中率很低,限于这个算法特点,所有的所有素数必须保存在内存,故不能求很大范围内的素数。

下表是我2^64以内的p1到p32-smooth数的个数。

n
Pn
2^64以内的
Pn-smooth数的个数
1
2
64
2
3
1344
3
5
13282
4
7
85348
5
11
378554
6
13
1381206
7
17
4164316
8
19
11169655
9
23
26587554
10
29
56643654
11
31
113399428
12
37
210499995
13
41
370466869
14
43
627484292
15
47
1020181037
16
53
1591363196
17
59
2395982361
18
61
3527728592
19
67
5050259345
20
71
7077350886
21
73
9759368423
22
79
13183354386
23
83
17528499627
24
89
22918160232
25
97
29457339259
26
101
37424970530
27
103
47121505151
28
107
58735924658
29
109
72644250191
30
113
89058878497
31
127
107598623619
32
131
129070232683



点评

是我错了,确实应该越来越多,不过你的答案有问题,都少了1  发表于 2013-10-24 12:49
你这个明显不对,<=2^64,这个范围是定下来了,素数因子越多,应该个数越少  发表于 2013-10-23 18:05
你用这些数干什么呢?我很好奇  发表于 2013-10-23 17:45
可以像30#的那样吗/forum.php?mod=redirect&goto=findpost&ptid=5167&pid=50813&fromuid=865 只对v存储,如果只是计算的话,我觉得可以不用存储v  发表于 2013-10-23 17:38
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-10-23 17:42:17 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <limits.h>
  3. #include <string.h>
  4. #include <malloc.h>

  5. #define MAX_LEVEL                32

  6. typedef unsigned long DWORD;

  7. #if defined(_MSC_VER)
  8.         typedef unsigned __int64 UINT64;
  9.         #define UINT64_FMT  "%I64u"

  10. #elif defined(__GNUC__)
  11.         typedef unsigned long long UINT64;
  12.         #define UINT64_FMT  "%llu"
  13. #else
  14.         #error don't support this compiler
  15. #endif

  16. const DWORD primes[]=
  17. {
  18.          2,  3,  5,  7, 11, 13, 17, 19,
  19.         23, 29, 31, 37, 41, 43, 47, 53,
  20.         59, 61, 67, 71, 73, 79, 83, 89,
  21.         97,101,103,107,109,113,127,131
  22. };

  23. typedef  struct _searchContent_tag
  24. {
  25.         struct search_tag
  26.         {
  27.                 UINT64 PI;                // product of some numbers
  28.                 UINT64 max;
  29.                 int idx;                // the index in array pArr
  30.                 int maxIdx;                // the index of last element
  31.                 UINT64* pArr;        // the address of primes power table
  32.         }arr[MAX_LEVEL];
  33.         UINT64 min;
  34.         UINT64 max;
  35.         int  maxLevel;                //level
  36. }SRCH_CONTENT_ST;

  37. void initSearchContent(int level, UINT64 min, UINT64 max, SRCH_CONTENT_ST* p)
  38. {
  39.         UINT64 prime,limit,pp;
  40.         int i,c;
  41.        
  42.         memset(p,0,sizeof(SRCH_CONTENT_ST));
  43.        
  44.         p->maxLevel=level-1;
  45.         p->max=max;         p->min=min;
  46.         p->arr[level-1].PI=1;
  47.         p->arr[level-1].max=max;
  48.         for (i=0;i<level;i++)
  49.         {
  50.                 prime=primes[i];
  51.                 limit=ULLONG_MAX/prime;
  52.                
  53.                 c=1;pp=1;
  54.                 while (pp<=limit)        //pp is power of prime
  55.                 { pp*=prime;c++; }
  56.                
  57.                 p->arr[i].pArr=(UINT64 *)malloc( sizeof(UINT64) * (c+1));
  58.                
  59.                 p->arr[i].pArr[0]=pp=1;        c=1;
  60.                 while (pp<=limit)
  61.                 { pp*=prime;p->arr[i].pArr[c++]=pp; }
  62.                
  63.                 p->arr[i].maxIdx= c-1;
  64.         }
  65. }

  66. void freeSearchContent( SRCH_CONTENT_ST* p)
  67. {
  68.         int i;
  69.         for (i=0;i<=p->maxLevel;i++)
  70.         {
  71.                 if ( p->arr[i].pArr!=NULL)
  72.                         free(p->arr[i].pArr);
  73.         }
  74.         memset(p,0,sizeof(SRCH_CONTENT_ST));
  75. }

  76. //recursive form
  77. void searchSmoothNums1( SRCH_CONTENT_ST* p, int order)
  78. {
  79.         int    idx;
  80.         /*
  81.             recurrence formula
  82.                 p->arr[order].PI= 1;
  83.                 p->arr[i-1].PI    = arr[i].pArr[ arr[i].idx] * arr[i+1].PI;       
  84.                 p->arr[i].max= p->max / p->arr[i].PI;
  85.         */

  86.         if (order==0)
  87.         {
  88.                 UINT64 min;
  89.                 UINT64 prod;

  90.                 min= (p->min + p->arr[0].PI -1)/p->arr[0].PI;  // min >= p->min/PI( when p->min % PI==0, min= p->min/PI)
  91.                
  92.                 if ( min > p->arr[0].max)
  93.                         return;

  94.                 idx=0;
  95.                 while (idx < p->arr[0].maxIdx && p->arr[0].pArr[idx]<min )
  96.                         idx++;
  97.                
  98.                 while ( p->arr[0].pArr[idx] <= p->arr[0].max && idx <= p->arr[0].maxIdx )
  99.                 {
  100.                         prod= p->arr[0].PI * p->arr[0].pArr[idx];
  101.                         idx++;
  102.                         printf(UINT64_FMT"\n",prod);
  103.                 }
  104.         }
  105.         else
  106.         {
  107.                 if ( p->arr[order].max==1 )
  108.                 {
  109.                         printf(UINT64_FMT"\n",p->arr[order].PI);
  110.                         return ;
  111.                 }
  112.                
  113.                 for (idx=0;  
  114.                         idx<= p->arr[order].maxIdx  && p->arr[order].pArr[idx] <= p->arr[order].max;
  115.                         idx++ )
  116.                 {
  117.                         p->arr[order].idx=idx;  
  118.                         p->arr[order-1].PI = p->arr[order].PI * p->arr[order].pArr[idx];
  119.                         p->arr[order-1].max= p->max / p->arr[order-1].PI;
  120.                         searchSmoothNums1(p,order-1);   //call itselft
  121.                 }
  122.                
  123.         }
  124. }


  125. #define M_FILL   0    //fill mode
  126. #define M_INC    1    //increase mode

  127. // iterative form
  128. // search all p[order+1] smooth number which between p->min and p->max
  129. // For exmaple
  130. //   order=0, search 2-smooth numbers
  131. //   order=1, search 3-smooth numbers
  132. //   order=2, search 5-smooth number
  133. void searchSmoothNums2( SRCH_CONTENT_ST* p, int order)
  134. {
  135.         UINT64 prod;
  136.         UINT64 PI;
  137.         UINT64 min;
  138.         int idx;

  139.         int i=order;
  140.         int mode=M_FILL;
  141.         /*
  142.             recurrence formula
  143.                 p->arr[order].PI= 1;
  144.                 p->arr[i-1].PI   = arr[i].pArr[ arr[i].idx] * arr[i+1].PI;       
  145.                 p->arr[i].max    = p->max / arr[i].PI;       
  146.         */
  147.        
  148.         p->arr[order].PI=1;
  149.         p->arr[order].max= p->max;

  150.         while (i<=order)
  151.         {
  152.                
  153.                 if (mode==M_FILL)  //fill mode
  154.                 {
  155.                         PI = p->arr[i].PI;
  156.                         if (i>0)
  157.                         {
  158.                                 p->arr[i].idx=0;
  159.                                 p->arr[i-1].PI = p->arr[i].PI;        //p->arr[i-1].PI= p->arr[i].PI;
  160.                                 p->arr[i-1].max= p->arr[i].max;
  161.                                 i--;                                                //forward to next level
  162.                         }
  163.                         else  // i==0
  164.                         {
  165.                                 min= (p->min + PI-1)/PI;        // min >= p->min/PI( when p->min % PI==0, min= p->min/PI)
  166.                        
  167.                                 if ( min > p->arr[0].max)
  168.                                 {
  169.                                         i++;                                        // backtrace
  170.                                         mode=M_INC;
  171.                                 }
  172.                                 else
  173.                                 {
  174.                                         idx=0;
  175.                                         while (idx < p->arr[0].maxIdx && p->arr[0].pArr[idx]<min )
  176.                                                 idx++;
  177.                                         if (  p->arr[0].pArr[idx] > p->arr[0].max || idx > p->arr[0].maxIdx)  
  178.                                                 i++;                                        // backtrace
  179.                                         else   //in this case, varible i don't change
  180.                                         {
  181.                                                 p->arr[0].idx=idx;
  182.                                                 printf(UINT64_FMT"\n",PI * p->arr[0].pArr[idx]);

  183.                                         }
  184.                                         mode=M_INC;                //change to increase mode
  185.                                 }
  186.                         }
  187.                 }
  188.                 else  //is increase mode
  189.                 {
  190.                         idx= p->arr[i].idx + 1;
  191.                         if (p->arr[i].pArr[idx] > p->arr[i].max || idx> p->arr[i].maxIdx)
  192.                                 i++;                // backtrace, mode don't change, still is increase mode
  193.                         else
  194.                         {
  195.                                 p->arr[i].idx=idx;
  196.                                 prod= p->arr[i].PI * p->arr[i].pArr[idx];

  197.                                 if (i==0)
  198.                                         printf(UINT64_FMT"\n",prod);
  199.                                 else
  200.                                 {
  201.                                         p->arr[i-1].max= p->max / prod;
  202.                                         if ( p->arr[i-1].max ==1)
  203.                                         {
  204.                                                 printf(UINT64_FMT"\n",prod);
  205.                                                 i++;                        // backtrace, mode don't change, still is increase mode
  206.                                         }
  207.                                         else
  208.                                         {
  209.                                                 p->arr[i-1].PI=prod;
  210.                                                 mode=M_FILL;        // change mode to fill mode
  211.                                                 i--;                        // forward to next level
  212.                                         }
  213.                                 }
  214.                         }
  215.                 }
  216.         }
  217. }

  218. void ref_searchSmoothNums(int order,UINT64 min, UINT64 max)
  219. {
  220.         UINT64 i,m;
  221.         int j,isSmooth;

  222.         for (i=min;i<=max;i++)
  223.         {
  224.                 for (m=i,isSmooth=0,j=0;j<order;j++)
  225.                 {
  226.                         while (m % primes[j]==0) m/=primes[j];
  227.                         if (m==1)
  228.                         {        isSmooth=1;        break;        }
  229.                 }
  230.                 if (isSmooth)
  231.                         printf(UINT64_FMT"\n",i);
  232.         }
  233. }

  234. void test()
  235. {
  236.         SRCH_CONTENT_ST searchContent;
  237.         UINT64 nMin,nMax;
  238.         int cs;//case

  239.         for (cs=0;cs<=1;cs++)
  240.         {
  241.                 if (cs==0)
  242.                 { nMin=1;  nMax=100; }
  243.                 else if (cs==1)
  244.                 { nMin=100;        nMax=200;        }

  245.                 initSearchContent(4,nMin,nMax,&searchContent);                       
  246.                
  247.                 printf("\n\nSearch smooth number ref_searchSmoothNums-------\n");
  248.                 ref_searchSmoothNums(4,nMin,nMax);
  249.                
  250.                 printf("\n\nSearch smooth number searchSmoothNums1-------\n");
  251.                 searchSmoothNums1( &searchContent,4-1);
  252.                
  253.                 printf("\n\nSearch smooth number searchSmoothNums2-------\n");
  254.                 searchSmoothNums2( &searchContent,4-1);

  255.                 freeSearchContent( &searchContent);
  256.         }
  257. }

  258. int main(int argc, char* argv[])
  259. {
  260.         test();
  261.         return 0;
  262. }
复制代码
1.什么是Smooth 数

如果一个整数的所有素因子都不大于B,我们称这个整数为B-Smooth数。用符号Pn表示表示第n个素数,例P1=2,P2=3,P3=5. 我们称素因子不大于Pn的Smooth数叫Pn-Smooth数。关于Smooth数更多的信息,请请参阅 Wiki词条 Smooth number http://en.wikipedia.org/wiki/Smooth_number.  P1 到 P9-Smooth 数可参阅下面的数列,这些数列在On-Line Encycolpedia of Integer Sequences http://oeis.org 给出

    2-smooth numbers: A000079 (2^i, i>=0)

    3-smooth numbers: A003586 (2^i ×3^j,i,j>=0)

    5-smooth numbers: A051037 (2^i ×3^j×5^k, i,j,k>=0)

    7-smooth numbers: A002473 (2^i×3^j×5^k×7^l, i,j,k,l>=0)

    11-smooth numbers: A051038 (etc...)

    13-smooth numbers: A080197

    17-smooth numbers: A080681

    19-smooth numbers: A080682

    23-smooth numbers: A080683



2. 如何得到smooth数

  基本上,我们有2种方法来生成一定范围内的smooth数。

1.   穷举法。基本方法是对指定范围内的每个数做分解素因数,如果其所有素因子都小于等于Pn,那个这个数就是Pn-smooth数。这种方法的优点是简单,缺点是速度较慢,只适合检查小范围内的整数。



2.构造法。其基本方法是用一个数组表示各个素因子的指数。例arr是一个数组,arr[1]表示素数p1(2)的指数,arr[2]表示素数p2(3)的指数,arr[3]表示素数p3(5)的指数. 欲求min和max之间的所有pn-smooth数, 则需要列举枚举这个数组的各个元素的取值。数组的各个元素的值需满足如下2个条件。

1. p[ i]>=0, 且p[ i] ^ arr[ i] <= max.  (p[ i]表示第i个素数,i>=1,i<=n)

2. min <=p[1]^arr[1] * p[2]^arr[2] * p[3]^arr[3] * …p[n]*arr[n] <=  max

对于一个包含n个元素的数组arr, 每个元素arr[ i] (1<=i<=n)各取一个数,就得到一个n维向量。如arr[1]=0, arr[2]=0, arr[3]=0可用3维向量(0,0,0)来表示,而arr[1]=1, arr[2]=0, arr[3]=0 则用3维向量(1,0,0)来表示。为了使得取得的所有n维向量既不重复也不遗漏。我们这里定义了比较2个n维向量的大小的规则

1.  如果2个n维向量a,b的所有分量都是相同的,我们说这两个n维向量是相同的。

2.  对于2个n维向量a,b(a的各个分量为a[1],a[2], …, a[n]),如果a[n]>b[n]我们说a>b.

3.  如果存在某个i,使得(1)对于所有的j (i<j<=n)都有a[j]=b[j]. (2) a[ i]>b[ i],那么我们说n维向量a>b.

  我们列举每个n维向量时,总是从小到到的进行,先是(0,0,0), 然后是(1,0,0), 然后是(2,0,0)…,然后是(0,1,0), (1,1,0), (2,1,0).   

未完待续

http://blog.csdn.net/liangbch/article/details/12186099
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-10-23 17:48:53 | 显示全部楼层
本帖最后由 chyanog 于 2013-10-23 17:54 编辑
hujunhua 发表于 2013-10-23 02:37
是由楼上链结中的程序改编的,效率当然也很高喽。

当list很大的时候,AppendTo会越来越慢,不如用Internal`Bag
  1. Module[{list, X, dp, checkb, pointer},
  2.    list = {};
  3.    X = {2, 3, 5};
  4.    checkb = {1, 1, 1};
  5.    pointer = {0, 0, 0};
  6.    Do[AppendTo[list, Min@checkb];
  7.     dp = 1 - Sign@(checkb - Last@list);
  8.     pointer += dp;
  9.     checkb += (list[[pointer]]*dp*X - checkb*dp)
  10.     , {2 10^4}];
  11.    list
  12.    ] // Hash // AbsoluteTiming
复制代码
{5.515315, 1434246505}
  1. \$ContextPath = Union@Append[\$ContextPath, "Internal`"];
  2. Module[{bag, X, dp, checkb, pointer},
  3.    bag = Bag[];
  4.    X = {2, 3, 5};
  5.    checkb = {1, 1, 1};
  6.    pointer = {0, 0, 0};
  7.    Do[
  8.     StuffBag[bag, Min@checkb];
  9.     dp = 1 - Sign@(checkb - BagPart[bag, -1]);
  10.     pointer += dp;
  11.     checkb += (BagPart[bag, pointer]*dp*X - checkb*dp),
  12.     {2 10^4}];
  13.    bag~BagPart~All
  14.    ] // Hash // AbsoluteTiming
复制代码
{0.905052, 1434246505}

点评

36#的Thread果然多余,去掉就更简洁了。内部包,果然强大,还没搞懂,有待研习。谢谢!  发表于 2013-10-23 18:35
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2021-2-25 12:51 , Processed in 0.086577 second(s), 24 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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