7
\$\begingroup\$

The partitions of an integer N are all the combinations of integers smaller than or equal to N and higher than 0 which sum up to N.

A relatively prime partition is an integer partition, but whose elements are (overall) coprime; or in other words, there is no integer greater than 1 which divides all of the parts.

Task

Given an integer as input, your task is to output the count of relatively prime partitions it has. Rather not surprised that there is an OEIS sequence for this. The aim is to shorten your code as much as possible, with usual code golf rules.

Also, you don't have to worry about memory errors. Your algorithm must only theoretically work for an arbitrarily big values of N, but it is fine if your language has certain limitations. You can assume that N will always be at least 1.

Test cases and Example

Let's take 5 as an example. Its integer partitions are:

1 1 1 1 1
1 1 1 2
1 1 3
1 2 2
1 4
2 3
5

From this, the first 6 only are relatively prime partitions. Note that the last one (formed by the integer in question only) must not be taken into account as a relatively prime partition (except for N=1) because its GCD is N.

N -> Output

1  -> 1
2  -> 1
3  -> 2
4  -> 3
5  -> 6
6  -> 7
7  -> 14
8  -> 17
9  -> 27
10 -> 34
\$\endgroup\$
1
  • \$\begingroup\$ related. \$\endgroup\$
    – Mr. Xcoder
    Commented Dec 17, 2017 at 12:13

6 Answers 6

7
\$\begingroup\$

JavaScript (ES6), 130 120 bytes

f=(n,d=n)=>d&&(n%d?0:(M=n=>n%++k?k>n||M(n):n/k%k&&-M(n/k))(n/d,k=1)*(P=n=>!k|n<0?0:n?P(n,k--)+P(n-++k):1)(k=d))+f(n,d-1)

Demo

f=(n,d=n)=>d&&(n%d?0:(M=n=>n%++k?k>n||M(n):n/k%k&&-M(n/k))(n/d,k=1)*(P=n=>!k|n<0?0:n?P(n,k--)+P(n-++k):1)(k=d))+f(n,d-1)

for(n = 1; n <= 30; n++) {
  console.log('a(' + n + ') = ' + f(n))
}

How?

This is recursively computing:

     /                  \     /                   \
    |  (M = n =>         |   |  (P = n =>          |
    |    n % ++k ?       |   |    !k | n < 0 ?     |
    |      k > n ||      |   |      0              |
    |      M(n)          |   |    :                |
sum |    :               | * |      n ?            | for d in divisors(n)
    |      n / k % k &&  |   |        P(n, k--) +  |
    |      - M(n / k)    |   |        P(n - ++k)   |
    |  )(n / d, k = 1)   |   |      :              |
    |                    |   |        1            |
    |                    |   |  )(k = d)           |
     \                  /     \                   /
        Möbius(n / d)            npartitions(d)
\$\endgroup\$
1
  • 1
    \$\begingroup\$ That explanation formatting is slick. Nice. \$\endgroup\$
    – notjagan
    Commented Dec 17, 2017 at 15:27
4
\$\begingroup\$

Pyth, 7 bytes

/iM./Q1

Test suite.

Explanation

/iM./Q1  | Full program.
         |
   ./Q   | The integer partitions (./) of the evaluated input (Q).
 iM      | Get the GCD (i) of each (M).
/     1  | Count (/) the 1's (1).

Pyth's behaviour comes in handy, since mapping with a 2-argument function automatically folds the command on the list, and the GCD of a one-element list is the element itself, so we don't have to handle that separately.

\$\endgroup\$
2
  • \$\begingroup\$ 7 second difference and a tie :D \$\endgroup\$
    – Leaky Nun
    Commented Dec 17, 2017 at 11:19
  • 1
    \$\begingroup\$ Alternative: s/1iM./ \$\endgroup\$
    – Mr. Xcoder
    Commented Dec 17, 2017 at 12:04
4
\$\begingroup\$

Pari/GP, 39 bytes

This sequence (A000837) is the Möbius transform of the partition numbers (A000041).

n->sumdiv(n,d,moebius(n/d)*numbpart(d))

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Wolfram Language (Mathematica), 35 bytes

Count[GCD@@@IntegerPartitions@#,1]&

Try it online!

This is my first Mathematica submission. Thanks to alephalpha for -4 bytes!

\$\endgroup\$
2
  • \$\begingroup\$ Count[GCD@@@IntegerPartitions@#,1]& \$\endgroup\$
    – alephalpha
    Commented Dec 17, 2017 at 11:42
  • \$\begingroup\$ @alephalpha Thank you very much! I was trying to use the shorthands to Map or Apply from the tips page but couldn't figure it out. \$\endgroup\$
    – Mr. Xcoder
    Commented Dec 17, 2017 at 11:43
2
\$\begingroup\$

Jelly, 7 bytes

Œṗg/€ċ1

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Swift, 202 185 bytes

Saved 17 bytes thanks to @Mr.Xcoder

func p(_ n:Int,_ m:[Int]=[])->[[Int]]{return 0<n ?(1...min(m.last ?? n,n)).flatMap{p(n-$0,m+[$0])}:[m]}
{n in n>1 ?p(n).filter{a in !(2...n).contains{m in !a.contains{$0%m>0}}}.count:1}

Try it online!

Explanation

func p(_ n:Int,_ m:[Int]=[])->[[Int]]{// Recursive helper function p where p(n, prefix) is
                                      // a list of all possiblie partitions of n
  return n > 0 ?                      // If n > 0:
    (1 ... min(m.last ?? n, n))       //   For i in range from 1 to min(n, last value in prefix):
      .flatMap{p(n - $0, m + [$0])}   //     Add p(n - i, prefix + i) to the return list
  :                                   // Else:
    [m]                               //   Return just the prefix
}                                      
{n in                                 // Main function:
  n > 1 ?                             // If n > 1:
    p(n).filter {a in                 //   Take the list of possible partitions of n where
      !(2...n).contains{m in          //   there is no integer m in the range from 2 to n where
        !a.contains{$0%m>0}           //   all elements in the partitioning divide m
      }
    }.count                           //   and return the length of the list
  :                                   // Else (if n == 1):
    1}                                //   Return 1
\$\endgroup\$
1
  • \$\begingroup\$ Closures are nearly always shorter ~ 185 bytes, no need to include var f= ~ Try it online! \$\endgroup\$
    – Mr. Xcoder
    Commented Dec 17, 2017 at 16:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.