2022-03-13 18:07:39 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Partitions an integer `num` into `div` summands and returns the `i`th
|
|
|
|
* of the partition.
|
|
|
|
*
|
2022-03-14 12:42:04 +00:00
|
|
|
* @param num Integer to be partitioned
|
|
|
|
* @param div Number of partitions
|
|
|
|
* @param i Index of partition
|
|
|
|
*
|
2022-03-13 18:07:39 +00:00
|
|
|
* @example
|
|
|
|
* num = 17
|
|
|
|
* div = 5
|
|
|
|
*
|
|
|
|
* partition(17, 5, 0) -> 4
|
|
|
|
* partition(17, 5, 1) -> 4
|
|
|
|
* partition(17, 5, 2) -> 3
|
|
|
|
* partition(17, 5, 3) -> 3
|
|
|
|
* partition(17, 5, 5) -> 3
|
|
|
|
*
|
|
|
|
* 17 = num = div * num + num % div = 4 + 4 + 3 + 3 + 3
|
|
|
|
* 1st 2nd 3rd 4th 5th
|
|
|
|
* i=0 i=1 i=2 i=3 i=4
|
|
|
|
*/
|
|
|
|
int partition(int num, int div, int i) {
|
|
|
|
return num / div + static_cast<int>(i < (num % div));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-03-14 12:42:04 +00:00
|
|
|
* Computes the partial sum of the first `i` integer `num` partitioned into
|
|
|
|
* `div` parts using `partition()`.
|
|
|
|
*
|
|
|
|
* sum_{j = 0}^i partition(num, div, j).
|
|
|
|
*
|
|
|
|
* @param num Integer to be partitioned
|
|
|
|
* @param div Number of partitions
|
|
|
|
* @param i Index of partition
|
|
|
|
*
|
2022-03-13 18:07:39 +00:00
|
|
|
* @example
|
|
|
|
* num = 17
|
|
|
|
* div = 5
|
|
|
|
*
|
|
|
|
* partition_sum(17, 5, 0) -> 4
|
|
|
|
* partition_sum(17, 5, 1) -> 8
|
|
|
|
* partition_sum(17, 5, 2) -> 11
|
|
|
|
* partition_sum(17, 5, 3) -> 14
|
|
|
|
* partition_sum(17, 5, 5) -> 17
|
|
|
|
*/
|
|
|
|
int partition_sum(int num, int div, int i) {
|
|
|
|
int sum = 0;
|
|
|
|
for (int j = 0; j <= i; ++j) {
|
|
|
|
sum += partition(num, div, j);
|
|
|
|
}
|
|
|
|
return sum;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Factorized a integer number `num` into two multiplicative factors.
|
|
|
|
* These factors are as close together as possible. This means for example for
|
|
|
|
* square numbers that the two factors are the square root of `num`.
|
|
|
|
*
|
|
|
|
* Assumes small numbers and therefore uses a simple linear search.
|
|
|
|
*
|
|
|
|
* The first few integers are factorized as follows:
|
|
|
|
*
|
|
|
|
* 0 = 1 * 0
|
|
|
|
* 1 = 1 * 1
|
|
|
|
* 2 = 1 * 2 (is prime)
|
|
|
|
* 3 = 1 * 3 (is prime)
|
|
|
|
* 4 = 2 * 2 (is square)
|
|
|
|
* 5 = 1 * 5 (is prime)
|
|
|
|
* 6 = 2 * 3
|
|
|
|
* 7 = 1 * 7 (is prime)
|
|
|
|
* 8 = 2 * 4
|
|
|
|
* 9 = 3 * 3 (is square)
|
|
|
|
* 10 = 2 * 5
|
|
|
|
* 11 = 1 * 11 (is prime)
|
|
|
|
* 12 = 3 * 4
|
|
|
|
* 13 = 1 * 13 (is prime)
|
|
|
|
* 14 = 2 * 7
|
|
|
|
* 15 = 3 * 5
|
|
|
|
* 16 = 4 * 4 (is square)
|
|
|
|
*
|
|
|
|
* @param num integer to be factorized
|
|
|
|
* @param factor [out] output parameter of length 2 where the two factors are
|
|
|
|
* written into.
|
|
|
|
*
|
|
|
|
* @example
|
|
|
|
* int factors[2];
|
|
|
|
* two_factors(15, factors); // -> factors = {3, 5}
|
|
|
|
*/
|
|
|
|
void two_factors(int num, int* factors) {
|
|
|
|
// In case of zero, set both to zero
|
|
|
|
if (!num) {
|
|
|
|
factors[0] = factors[1] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure `num` is positive
|
|
|
|
if (num < 0) {
|
|
|
|
num *= -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set initial factorization (this always works)
|
|
|
|
factors[0] = 1;
|
|
|
|
factors[1] = num;
|
|
|
|
|
2022-03-14 12:42:04 +00:00
|
|
|
// Check all numbers `i` until the integer square-root
|
2022-03-13 18:07:39 +00:00
|
|
|
for (int i = 2; i * i <= num; ++i) {
|
|
|
|
// Check if `i` is a divisor
|
|
|
|
if (!(num % i)) {
|
|
|
|
// Update factors as `i` divides `num`
|
|
|
|
factors[0] = i;
|
|
|
|
factors[1] = num / i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|