zoelgriffiths/pascals

Refactoring of Pascal Counting

Opened this issue · 1 comments

rioj7 commented

By using a generator function and collection.Counter the code can be a lot smaller and also less memory usage

import math
from collections import Counter

def generatePascalNumbers(row_limit):
    #Below I am dictating the rows and columns I will compute cell values for.

    #(I have excluded the outer two diagonals (on either side) of Pascal's triangle, because we know that the numbers in those diagonals (across the whole triangle) are an infinite number of 1s and two appearances of all other positive integers apart from 2 (for which there is only one appearance).)

    for n in range(4,row_limit):
        nFac = math.factorial(n)
        for r in range(2,n-1):
            yield nFac /(math.factorial(n-r)*math.factorial(r))


def search(row_limit):
    countTriangle = Counter(generatePascalNumbers(row_limit))

    #Below I am checking how many times each distinct number appears in the cells we've generated. If a number appears more than twice (therefore more than four times across the whole triangle) I am storing both the number and the minimum number of times it appears across the whole triangle.

    for number, count in countTriangle.items():
        if count >= 3:
            print ("The number {0} appears at least {1} times across the whole triangle".format(number, count+2))

search(501)

Why make a dict from the zip()?

    final_info = dict(zip(which_ones,how_many_times))
    
    for entry,frequency in final_info.items(): 
        print ("The number {0} appears at least {1} times across the whole triangle".format(entry,frequency))

Can be refactored to

    for entry,frequency in zip(which_ones, how_many_times): 
        print ("The number {0} appears at least {1} times across the whole triangle".format(entry,frequency))

zip() is an iterator, no need to convert it to a list or dict before using it in a for loop, saves memory of constructing the list or dict. The zip arguments could be infinite iterators.

You could also use itertools.accumulate() to reduce the effort for math.factorial(): https://gist.github.com/achampion/cd0ac77c5b9a3716936445623bccd8d3