Skip to content

Instantly share code, notes, and snippets.

@Centrinia
Created December 13, 2019 09:49
Show Gist options
  • Save Centrinia/80a48dd0e87740839028670b27210040 to your computer and use it in GitHub Desktop.
Save Centrinia/80a48dd0e87740839028670b27210040 to your computer and use it in GitHub Desktop.
def main():
import argparse
parser = argparse.ArgumentParser(description='Generate Pascal\'s Triangle')
parser.add_argument('out', help='output file')
parser.add_argument('--width', '-w', default=1024, help='image width in pixels', type=int)
parser.add_argument('--modulus', '-m', help='modulus', type=int)
parser.add_argument('--isosceles', action='store_true', help='render isosceles triangle')
parser.add_argument('--verbose', '-v', action='count', default=0)
exgroup = parser.add_mutually_exclusive_group(required=True)
exgroup.add_argument('--rows', '-r', help='number of rows of Pascal\'s triangle', type=int)
exgroup.add_argument('--iterates', '-i', help='rows per pixel', type=int)
args = parser.parse_args()
n = args.width
if args.iterates:
m = args.iterates
elif args.rows:
m = (args.rows + args.width - 1) // args.width
import imageio
import numpy as np
p = args.modulus
arr = np.zeros(n * m + 1, dtype=np.int64)
arr[0] = 1
img = np.zeros((n, n + 1), dtype=np.int64)
for k in range(n):
img_acc = np.zeros(n * m, dtype=np.int64)
for j in range(m):
i = k * m + j
img_acc += arr[:-1]
arr[1:i + 2] += arr[:i + 1]
arr[0] = 1
arr[i + 1] = 1
if p:
arr %= p
row = np.sum(img_acc.reshape((n, m)), axis=1)[:k + 1]
if args.isosceles:
if k % 2 == 0:
img[k, (n - k) // 2:(n + k + 2) // 2] = row * 2
else:
img[k, (n - k) // 2:(n + k + 2) // 2] += row
img[k, (n - k + 2) // 2:(n + k + 4) // 2] += row
else:
img[k, :k + 1] += row
if args.verbose >= 1:
print(f'{k/(n-1):2.2%} complete')
img -= img.min()
img = img * 255 // np.max(img)
img = img.astype(np.uint8)
imageio.imwrite(args.out, img)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment