A number as it's prime number parts

前端 未结 3 2054
隐瞒了意图╮
隐瞒了意图╮ 2020-12-19 12:23

I have to print the number of ways you can represent a given number as it\'s prime number parts.

Let me clarify: Let\'s say I have been given this number 7. Now, fir

相关标签:
3条回答
  • 2020-12-19 13:15

    The concept you are searching for is the "prime partitions" of a number. S partition of a number is a way of adding numbers to reach the target; for instance, 1+1+2+3 is a partition of 7. If all the addends are prime, then the partition is a prime partition.

    I think your example is wrong. The number 7 is usually considered to have 3 prime partitions: 2+2+3, 2+5, and 7. The order of the addends doesn't matter. In number theory the function that counts prime partitions is kappa, so we would say kappa(7) = 3.

    The usual calculation of kappa is done in two parts. The first part is a function to compute the sum of the prime factors of a number; for instance, 42=2·3·7, so sopf(42)=12. Note that sopf(12)=5 because the sum is over only the distinct factors of a number, so even though 12=2·2·3, only one 2 is included in the calculation of the sum.

    Given sopf, there is a lengthy formula to calculate kappa; I'll give it in LaTeX form, since I don't know how to enter it here: \kappa(n) = \frac{1}{n}\left(\mathrm{sopf}(n) + \sum_{j=1}^{n-1} \mathrm{sopf}(j) \cdot \kappa(n-j)\right).

    If you actually want a list of the partitions, instead of just the count, there is a dynamic programming solution that @corsiKa pointed out.

    I discuss prime partitions in more detail at my blog, including source code to produce both the count and the list.

    0 讨论(0)
  • 2020-12-19 13:18

    Here's an efficient implementation which uses dynamic programming like corsiKa suggests, but does not use the algorithm he describes.

    Simply: if n is reachable via k distinct paths (including the single-step one, if it exists), and p is prime, then we construct k paths to n+p by appending p to all paths to n. Considering all such n < N will produce an exhaustive list of valid paths to N. So we just sum the number of paths so discovered.

    #include <iostream>
    
    int primes_all[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
    
    const int N_max = 85;
    typedef long long ways;
    ways ways_to_reach_N[N_max + 1] = { 1 };
    
    int main()
    {
        // find all paths
        for( int i = 0; i <= N_max; ++i ) {
            ways ways_to_reach_i = ways_to_reach_N[i];
    
            if (ways_to_reach_i) {
                for( int* p = primes_all; *p <= N_max - i && p < (&primes_all)[1]; ++p ) {
                    ways_to_reach_N[i + *p] += ways_to_reach_i;
                }
            }
        }
    
        // eliminate single-step paths
        for( int* p = primes_all; *p <= N_max && p < (&primes_all)[1]; ++p ) {
            --ways_to_reach_N[*p];
        }
    
        // print results
        for( int i = 1; i <= N_max; ++i ) {
            ways ways_to_reach_i = ways_to_reach_N[i];
    
            if (ways_to_reach_i) {
                std::cout << i << " -- " << ways_to_reach_i << std::endl;
            }
        }
    
        return 0;
    }
    
    • Demo: http://ideone.com/xWZT8v

    Replacing the typedef ways with a big integer type is left as an exercise to the reader.

    0 讨论(0)
  • 2020-12-19 13:20

    Dynamic programming is your friend here.

    Consider the number 27.

    If 7 has 5 results, and 20 has 732 results, then you know that 27 has at least (732 * 5) results. You can use a two variable system (1 + 26, 2 + 25 ... etc) using the precomputed values for those as you go. You don't have to recompute 25 or 26 because you already did them.

    0 讨论(0)
提交回复
热议问题