#include <assert.h>
#include <solution/2711.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

int differentElementNum(int *elem, int size)
{
    int sum = 0;
    int *temp = NULL;
    for (int i = 0; i < size; i++)
    {
        bool flag = true;
        // check same elem
        for (int j = 0; j < sum; j++)
            if (elem[i] == temp[j])
                flag = false;
        // if not in temp, add to temp
        if (flag)
        {
            temp = realloc(temp, ++sum * sizeof(int));
            temp[sum - 1] = elem[i];
        }
    }

    free(temp);
    return sum;
}

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int **differenceOfDistinctValues(int **grid, int gridSize, int *gridColSize, int *returnSize, int **returnColumnSizes)
{
    int **answer = (int **)malloc(sizeof(int *) * gridSize);
    *returnColumnSizes = (int *)malloc(gridSize * sizeof(int));
    for (int r = 0; r < gridSize; r++)
    {
        answer[r] = (int *)malloc(sizeof(int) * gridColSize[r]);
        (*returnColumnSizes)[r] = gridColSize[r];
        for (int c = 0; c < gridColSize[r]; c++)
        {
            // calc topLeft array
            int *topLeftElements = NULL;
            int topLeftSize = 0;
            int topLeft = 0;
            for (int x = r - 1, y = c - 1; x >= 0 && y >= 0; x--, y--)
            {
                // add element to array
                topLeftElements = realloc(topLeftElements, ++topLeftSize * sizeof(int));
                topLeftElements[topLeftSize - 1] = grid[x][y];
            }
            topLeft = differentElementNum(topLeftElements, topLeftSize);

            // calc bottomRight array
            int *bottomRightElements = NULL;
            int bottomRightSize = 0;
            int bottomRight = 0;
            for (int x = r + 1, y = c + 1; x < gridSize && y < gridColSize[r]; x++, y++)
            {
                bottomRightElements = realloc(bottomRightElements, ++bottomRightSize * sizeof(int));
                bottomRightElements[bottomRightSize - 1] = grid[x][y];
            }
            bottomRight = differentElementNum(bottomRightElements, bottomRightSize);

            answer[r][c] = abs(topLeft - bottomRight);
            free(bottomRightElements);
            free(topLeftElements);
        }
    }

    *returnSize = gridSize;
    return answer;
}
