I recently completed the Pascal's Triangle challenge on leetcode. I would like to have my code reviewed.
You don't need a leetcode account to see the description of the challenge linked above, but for completeness I'm pasting the description here.
Given an integer numRows, return the first numRows of Pascal's triangle.
In Pascal's triangle, each number is the sum of the two numbers directly above it as shown:
I think your review should touch the following points:
- Code correctness (the code passed all leetcode tests, but there might be some bug/UB hiding somewhere that neither I nor leetcode caught)
- Code performance (algorithm and implementation details)
- Code quality (the so-called "best practices" -- it's okay to be subjective)
- Stick to C99 without compiler extensions or anything non-standard
I encourage you to be pedantic about UB, memory management, adherence to the C standard, etc.
One last note: Leetcode forces me to use this exact function signature
int **generate(int numRows, int *returnSize, int **returnColumnSizes);
So that's something I can't change.
Finally, here's my code:
// solution.c
#include <stdlib.h>
#include <string.h>
int **generate(int numRows, int *returnSize, int **returnColumnSizes)
{
int **ret = malloc((size_t)numRows * sizeof(int *));
*returnColumnSizes = malloc((size_t)numRows * sizeof(int));
*returnSize = numRows;
for (size_t i = 0; i < numRows; i += 1)
{
size_t size = i + 1;
(*returnColumnSizes)[i] = (int)size;
ret[i] = malloc((size_t)size * sizeof(int));
ret[i][0] = 1;
ret[i][i] = 1;
for (size_t j = 1; j < i; j += 1)
{
ret[i][j] = ret[i - 1][j - 1] + ret[i - 1][j];
}
}
return ret;
}
Here's the driver code I used to test it:
// main.c
#include <stdlib.h>
#include <stdio.h>
int **generate(int numRows, int *returnSize, int **returnColumnSizes);
int main()
{
int *returnColumnSizes;
int returnSize;
int **rows = generate(5, &returnSize, &returnColumnSizes);
for (size_t i = 0; i < returnSize; i += 1)
{
for (size_t j = 0; j < returnColumnSizes[i]; j += 1)
{
printf("%d ", rows[i][j]);
}
free(rows[i]);
printf("\n");
}
free(rows);
return EXIT_SUCCESS;
}
Here's how I compile and run the code:
# run.sh
CC="clang"
CFLAGS="-std=c99 -Werror -Wall -Wpedantic -Wconversion"
$CC $CFLAGS ./solution.c ./main.c -o ./main && ./main
./run.sh