#include <stdio.h>
#include <stdlib.h>

void combinations(int **sets, int *sizes, int *indices, int n, int depth, int *output, int *count) {
    if (depth == n) {
        // base case: we have selected one element from each set
        // print the combination
        for (int i = 0; i < n; i++) {
            printf("%d", sets[i][indices[i]]);
        }
        printf("\n");
        // add the combination to the output array
        for (int i = 0; i < n; i++) {
            output[*count * n + i] = sets[i][indices[i]];
        }
        (*count)++;
        return;
    }
    // recursive case: select one element from the current set and move on to the next set
    for (int i = 0; i < sizes[depth]; i++) {
        indices[depth] = i;
        combinations(sets, sizes, indices, n, depth + 1, output, count);
    }
}

int main() {
    int n = 2;
    int *sizes = malloc(n * sizeof(int));
    sizes[0] = 3;
    sizes[1] = 2;
    int **sets = malloc(n * sizeof(int *));
    sets[0] = malloc(3 * sizeof(int));
    sets[0][0] = 1;
    sets[0][1] = 2;
    sets[0][2] = 3;
    sets[1] = malloc(2 * sizeof(int));
    sets[1][0] = 2;
    sets[1][1] = 5;
    int *indices = calloc(n, sizeof(int));
    int count = 0;
    int *output = malloc(n * sizes[0] * sizes[1] * sizeof(int));
    combinations(sets, sizes, indices, n, 0, output, &count);
    printf("Total combinations: %d\n", count);
    for (int i = 0; i < count; i++) {
        for (int j = 0; j < n; j++) {
            printf("%d", output[i * n + j]);
        }
        printf("\n");
    }
    free(sizes);
    free(sets[0]);
    free(sets[1]);
    free(sets);
    free(indices);
    free(output);
    return 0;
}
