HiveBrain v1.2.0
Get Started
← Back to all entries
snippetjavascriptMinor

Printing out Pascal's Triangle in row-major format

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
formatmajorpascaltriangleprintingrowout

Problem

Here's the problem statement:


Given an integer value, print out Pascal's Triangle to the
corresponding depth in row-major format:


Input Sample:

6




Output Sample:

1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1


I need some practice with recursion, so I tried that approach:

var pascalDepth = parseInt(line, 10); //The input integer is provided on a single line as a text value, so this handles it.
var testTriangle = pascalTriangle(pascalDepth);
var output = [];

for(var i = 0; i  0) {
        var triangleLine = [];
        for (var i = 0; i < triangle.length; i++) {
            if (typeof triangle[triangle.length - 1][i - 1] === 'undefined') {
                triangleLine.push(1);
            } else {
                triangleLine.push((triangle[triangle.length - 1][i - 1] + triangle[triangle.length - 1][i]));
            }
        }
        triangleLine.push(1);
        triangle.push(triangleLine);
    } else {
        triangle.push([1]);
    }
    return pascalTriangle(totalLines, triangle);
}

Solution

Like the Fibonacci sequence, calculating Pascal's triangle recursively using a pure functional approach wouldn't be very efficient, since you would repeatedly compute many of the entries.

You've implemented a recursive solution with memoization, which is smarter. However, with memoization, the solution is stylistically iterative. Consider the following function, which behaves identically to yours, but is written in a more straightforward manner:

function pascalTriangle(totalLines) {
    var triangle = [];
    while (triangle.length  0) {
            var triangleLine = [];
            for (var i = 0; i < triangle.length; i++) {
                if (typeof triangle[triangle.length - 1][i - 1] === 'undefined') {
                    triangleLine.push(1);
                } else {
                    triangleLine.push((triangle[triangle.length - 1][i - 1] + triangle[triangle.length - 1][i]));
                }
            }
            triangleLine.push(1);
            triangle.push(triangleLine);
        } else {
            triangle.push([1]);
        }
    }
    return triangle;
}


You could consider your "recursion" to be a fancy goto. Alternatively, you could conclude that Pascal's triangle does not lend itself to recursion.

That said, your implementation could be more compact. Think of deriving the next line this way:

[ , 1, 3, 3, 1]
+ [1, 3, 3, 1,  ]
—————————————————
  [1, 4, 6, 4, 1]


Then, you can use higher-level thinking: make two arrays with the appropriate offset, and find the sums of the corresponding elements.

function pascalTriangle(totalLines, triangle) {
    // Helper function to add corresponding elements of two arrays
    function sum(a, b) {
        return a.map(function(_, i) {
            return a[i] + b[i];
        });
    };

    if (triangle == null) {                 // Initial call with just one parameter
        triangle = [[1]];
    }
    if (totalLines === triangle.length) {   // Final case
        return triangle;
    }
    var prevLine = triangle[triangle.length - 1];
    var nextLine = sum([0].concat(prevLine), prevLine.concat([0]));
    return arguments.callee(totalLines, triangle.concat([nextLine]));
}


I've used arguments.callee for the function to refer to itself, so that if you rename the function (or make it anonymous), it can still work.

Code Snippets

function pascalTriangle(totalLines) {
    var triangle = [];
    while (triangle.length < totalLines) {
        if (triangle.length > 0) {
            var triangleLine = [];
            for (var i = 0; i < triangle.length; i++) {
                if (typeof triangle[triangle.length - 1][i - 1] === 'undefined') {
                    triangleLine.push(1);
                } else {
                    triangleLine.push((triangle[triangle.length - 1][i - 1] + triangle[triangle.length - 1][i]));
                }
            }
            triangleLine.push(1);
            triangle.push(triangleLine);
        } else {
            triangle.push([1]);
        }
    }
    return triangle;
}
[ , 1, 3, 3, 1]
+ [1, 3, 3, 1,  ]
—————————————————
  [1, 4, 6, 4, 1]
function pascalTriangle(totalLines, triangle) {
    // Helper function to add corresponding elements of two arrays
    function sum(a, b) {
        return a.map(function(_, i) {
            return a[i] + b[i];
        });
    };

    if (triangle == null) {                 // Initial call with just one parameter
        triangle = [[1]];
    }
    if (totalLines === triangle.length) {   // Final case
        return triangle;
    }
    var prevLine = triangle[triangle.length - 1];
    var nextLine = sum([0].concat(prevLine), prevLine.concat([0]));
    return arguments.callee(totalLines, triangle.concat([nextLine]));
}

Context

StackExchange Code Review Q#25333, answer score: 2

Revisions (0)

No revisions yet.