The challenge

Create a function named divisors/Divisors that takes an integer n > 1 and returns an array with all of the integer’s divisors(except for 1 and the number itself), from smallest to largest. If the number is prime return the string ‘(integer) is prime’ (null in C#) (use Either String a in Haskell and Result<Vec<u32>, String> in Rust).

Example:

1
2
3
divisors(12); // results in {2, 3, 4, 6}
divisors(25); // results in {5}
divisors(13); // results in NULL

The solution in C

Option 1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include <stddef.h>

void divisors(unsigned n, size_t *z, unsigned *array) {
  *z = 0;
  
  for (int i = 2; i <= (n / 2); i++) {
    if (n % i == 0)
      array[(*z)++] = i;
  }
}

Option 2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include <stddef.h>

void divisors(unsigned n, size_t *length, unsigned array[]) {
    int i;
    int j = 0;
    for (i = 2; i < (int) n; i++) {
      if (n % i == 0) {
        array[j] = i;
        j++;
      }
    }
    *length = (size_t) j;
}

Option 3:

1
2
3
4
5
6
7
8
9
#include <stddef.h>

void divisors(unsigned n, size_t *z, unsigned *array) {
  int len = 0;
  for (unsigned i = 2; i < n; i++) {
    if (n % i == 0) array[len++] = i;
  }
  *z = len;
}

Test cases to validate our solution

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <criterion/criterion.h>
#include <stddef.h>

extern void tester(unsigned n, size_t length, const unsigned expected[length]);

Test(Sample_Tests, should_pass_all_tests)
{
  { unsigned n =  15; const unsigned expected[2] = {3, 5};              tester(n, 2, expected); }
  { unsigned n = 253; const unsigned expected[2] = {11, 23};            tester(n, 2, expected); }
  { unsigned n =  24; const unsigned expected[6] = {2, 3, 4, 6, 8, 12}; tester(n, 6, expected); }
  { unsigned n =  25; const unsigned expected[1] = {5};                 tester(n, 1, expected); }
  { unsigned n =  13; const unsigned *expected = NULL;                  tester(n, 0, expected); }
  { unsigned n =   3; const unsigned *expected = NULL;                  tester(n, 0, expected); }
  { unsigned n =  29; const unsigned *expected = NULL;                  tester(n, 0, expected); }
}