Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Changes from Version 1 of BitArrayVsArrayOfBoolsExample

Show
Ignore:
Author:
gim (IP: 158.75.88.16)
Timestamp:
06/03/08 23:52:20 (16 years ago)
Comment:

First version

Legend:

Unmodified
Added
Removed
Modified
  • BitArrayVsArrayOfBoolsExample

    v0 v1  
     1= Solution to Google Treasure Hunt 2008 - Task 4 = 
     2 
     3The program below can be used to solve a particular instance of the task presented at http://treasurehunt.appspot.com (Task 4, 2008). You are given few numbers, e.g. [1111, 137, 13, 3]. Your task is to find smallest prime that is a sum of 1111 consecutive primes, sum of 137 consecutive primes and so on. 
     4 
     5The values are placed in limits array, but you can also pass them as arguments (in descending order!) from command line: 
     6{{{ 
     7    ./TreasureHunt4 799 415 63 31 
     8}}} 
     9 
     10The code allows to compare [http://dsource.org/projects/tango/docs/current/tango.core.BitArray.html BitArray] with array of booleans. BitArray is a bit slower, but should occupy less memory. Implementation uses Atkin sieve. 
     11 
     12Code can be compiled with debug option for additional informations. 
     13 
     14{{{ 
     15#!d 
     16/* Michal 'GiM' SpadliƄski             <gim913 & gmail * com > 
     17 *  
     18 * Google TreasureHunt task 4 solution 
     19 * http://treasurehunt.appspot.com/ 
     20 */ 
     21module TreasureHunt4; 
     22 
     23//version = BitArray; 
     24 
     25import tango.io.Stdout; 
     26import tango.time.StopWatch; 
     27import Integer = tango.text.convert.Integer; 
     28version ( BitArray ) 
     29    import tango.core.BitArray; 
     30 
     31 
     32static const int sqrt_val = 2500; 
     33// descending order 
     34int[] limits = [1111, 137, 13, 3]; 
     35 
     36 
     37ulong primes[]; 
     38static this() 
     39{    
     40    StopWatch timer; 
     41    timer.start; 
     42    some_small_primes = atkin_sieve; 
     43    foreach (k, a; some_small_primes) 
     44        if (a) 
     45            primes ~= k; 
     46    auto temp = timer.stop; 
     47    Stdout.formatln ("primes table generated in {} seconds with {} entries", temp, primes.length); 
     48} 
     49 
     50class PrimesSum 
     51{ 
     52private: 
     53        ulong _sum; 
     54        int start; 
     55        int limit; 
     56public: 
     57    this(int lim) 
     58    {    
     59        limit = lim; 
     60        for (int j=0; j<limit; ++j) 
     61            _sum += primes[j]; 
     62    } 
     63     
     64    void next() 
     65    {    
     66        _sum -= primes[start]; 
     67        _sum += primes[start+limit]; 
     68        ++start; 
     69    } 
     70    void previous() 
     71    {    
     72        --start; 
     73        _sum -= primes[start+limit]; 
     74        _sum += primes[start]; 
     75    } 
     76 
     77    int opCmp(PrimesSum b) { return _sum - b.sum; } 
     78    int opEquals(PrimesSum b) { return _sum == b.sum; } 
     79 
     80    uint sum() { return _sum; } 
     81 
     82    char[] toString() 
     83    {    
     84        char[100] tmp = void; 
     85        return Integer.format (tmp, _sum, Integer.Style.Unsigned, Integer.Flags.None).dup; 
     86    } 
     87} 
     88 
     89void main(char[][] argv) 
     90{ 
     91    PrimesSum[] prSums; 
     92    StopWatch timer; 
     93 
     94    if (argv.length > 1) 
     95    {    
     96        limits = []; 
     97        foreach (char[] arg; argv[1..$]) 
     98            limits ~= Integer.toInt(arg); 
     99        Stdout(limits).newline; 
     100    } 
     101 
     102    timer.start; 
     103 
     104    prSums.length = limits.length; 
     105    foreach (a, ref b; prSums) 
     106        b = new PrimesSum(limits[a]); 
     107 
     108OUTER_LOOP: 
     109    for(;;) 
     110    {    
     111        // Sum must be a prime 
     112        try { 
     113            while (1) 
     114            {    
     115                if (some_small_primes[prSums[0].sum]) 
     116                    break; 
     117                else 
     118                    prSums[0].next; 
     119            } 
     120        } catch (Exception e) { 
     121            assert (0, "Increase the value of sqrt_val in the source file"); 
     122        } 
     123        debug Stdout.formatln ("0: {} {}", prSums[0].sum, prSums[0].start); 
     124 
     125        // check if all the other, smaller sums, sum to the same number 
     126        for (int idx=1; idx<prSums.length; ++idx) 
     127        {    
     128            while (prSums[idx] < prSums[0]) 
     129                prSums[idx].next; 
     130            debug Stdout.formatln ("{}: {} {}", idx, prSums[idx].sum, prSums[idx].start); 
     131            if (prSums[idx] != prSums[0]) 
     132            {    
     133                debug Stdout ("differ2").newline; 
     134                prSums[0].next; 
     135                for (int i=1; i<=idx; ++i) 
     136                    while (prSums[i] > prSums[0]) 
     137                        prSums[i].previous; 
     138                continue OUTER_LOOP; 
     139            } 
     140        } 
     141        // we got you 
     142        break; 
     143    } 
     144    auto temp = timer.stop; 
     145    Stdout ("The Answer to the Great Question ...") 
     146        .formatln ("Of Life, the Universe and Everything: {}", prSums[0]); 
     147    Stdout  ("input data: ") (limits).newline; 
     148    Stdout.formatln ("Finding answer took {} seconds", temp); 
     149} 
     150 
     151T atkin(T, int sqrt_limit)() 
     152{ 
     153    const long limit = sqrt_limit*sqrt_limit; 
     154    T firstSet; 
     155    firstSet.length = limit; 
     156     
     157    firstSet[2] = 1; 
     158    firstSet[3] = 1; 
     159             
     160    for (auto x = 1; x<sqrt_limit; ++x) 
     161    { 
     162        for (auto y=1; y<sqrt_limit; ++y) 
     163        { 
     164            auto n = 4 * x*x + y*y; 
     165            if (n < limit && ((n % 12) == 1 || (n % 12) == 5)) 
     166                firstSet[n] = cast(bool)1^firstSet[n]; 
     167            n = 3 * x*x + y*y; 
     168            if (n < limit && ((n % 12) == 7)) 
     169                firstSet[n] = cast(bool)1^firstSet[n]; 
     170            n = 3 * x*x - y*y; 
     171            if (n < limit && x > y && ((n % 12) == 11)) 
     172                firstSet[n] = cast(bool)1^firstSet[n]; 
     173        } 
     174    }    
     175    for (int n=5; n<sqrt_limit; ++n) 
     176    {    
     177        if (firstSet[n]) 
     178            for (int k=1, j=n*n; j*k<limit; ++k) 
     179                firstSet[k*j] = 0; 
     180    }    
     181    return firstSet; 
     182}        
     183     
     184version ( BitArray ) 
     185{    
     186    static const BitArray some_small_primes; 
     187    alias atkin!(BitArray, sqrt_val) atkin_sieve; 
     188} else  { 
     189    static const bool[] some_small_primes; 
     190    alias atkin!(bool[], sqrt_val) atkin_sieve; 
     191}    
     192}}} 
     193 
     194Here is sample run of a program on Core Duo 1.7 with sqrt_val set to 2630, this also show how fast D is: 
     195 
     196{{{ 
     197primes table generated in 1.07 seconds with 471342 entries 
     198[ 799, 415, 63, 31 ] 
     199The Answer to the Great Question ...Of Life, the Universe and Everything: 6814289 
     200input data: [ 799, 415, 63, 31 ] 
     201Finding answer took 0.00 seconds 
     202}}}