
/**
 * C (m, n): select m from n elements, 0 <= m <= n
 * C(m, n) = n! / (m! * (n-m)!)
 * C(0, n) = 1
 * C(m+1, n) = C(m, n) * ((n-m) / (m+1))
 */
#include <vector>
#include <iostream>

using namespace std;

/*  C (m, n): select m from n elements, 0 <= m <= n
 * C(m, n) = n! / (m! * (n-m)!)
 * C 
 */

vector<int> getRow(int rowIndex) {
    vector<int> result(rowIndex+1, 1);
    
    //calcuate half, and mirrow to whole array
    int size = rowIndex/2+1;
    for (int i = 1; i < size; ++i) {
        int value = 0;
        // To prevent from integer overflow
        if (rowIndex >= 30) {
            value = int(((long long)result[i-1]) * (rowIndex-i+1) / i);
        } else {
            // but also reduce type casting if not neccessary
            value = result[i-1] * (rowIndex-i+1) / i;
        }
        result[rowIndex-i] = result[i] = value;
    }
    
    return result;
}

void printV(vector<int>  v) {
    size_t si = v.size();
    for (int i = 0; i < si; ++i) {
        cout << v[i] << ", ";
    }
    
    cout << endl;
}

int main (int argc, const char * argv[]) {
    
    cout << "Pascal's Triangle of 7:" << endl;
    printV(getRow(7));
    
    cout << endl << "Pascal's Triangle of 21:" << endl;
    printV(getRow(21));
    return 0;
}


