NSSC/Exercise_01/src/utils.h

116 lines
2.8 KiB
C

/**
* Partitions an integer `num` into `div` summands and returns the `i`th
* of the partition.
*
* @param num Integer to be partitioned
* @param div Number of partitions
* @param i Index of partition
*
* @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));
}
/**
* 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
*
* @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;
// Check all numbers `i` until the integer square-root
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;
}
}
}