|
| 1 | +# https://www.codewars.com/kata/binomial-expansion/train/python |
| 2 | + |
| 3 | +import math |
| 4 | + |
| 5 | +def axb_extract(expr): |
| 6 | + expr = expr[::-1] |
| 7 | + parts = expr.split('+', 1) |
| 8 | + if len(parts) != 2: |
| 9 | + parts = expr.split('-', 1) |
| 10 | + parts[0] += '-' |
| 11 | + |
| 12 | + a_str = parts[1] |
| 13 | + a_str = a_str[1:] |
| 14 | + a_str = a_str[::-1] |
| 15 | + if a_str == '' or a_str == '-': |
| 16 | + a_str += '1' |
| 17 | + |
| 18 | + a = int(a_str) |
| 19 | + x = parts[1][0] |
| 20 | + b = int(parts[0][::-1]) |
| 21 | + |
| 22 | + return a, x, b |
| 23 | + |
| 24 | +def binom_coef(n): |
| 25 | + top = list(range(n, math.floor((n+1)/2), -1)) |
| 26 | + bot = list(range(1, math.ceil((n+1)/2), 1)) |
| 27 | + |
| 28 | + for i in range(1, len(top)): |
| 29 | + top[i] *= top[i-1] |
| 30 | + bot[i] *= bot[i-1] |
| 31 | + |
| 32 | + coef = [1] |
| 33 | + for i in range(len(top)): |
| 34 | + coef.append(top[i]//bot[i]) |
| 35 | + |
| 36 | + coef2 = coef if n % 2 == 1 else coef[:-1] |
| 37 | + coef += coef2[::-1] |
| 38 | + |
| 39 | + return coef |
| 40 | + |
| 41 | +def expand(expr): |
| 42 | + parts = expr.split('^', 1) |
| 43 | + exponent = int(parts[1]) |
| 44 | + |
| 45 | + if exponent == 0: |
| 46 | + return '1' |
| 47 | + elif exponent == 1: |
| 48 | + return parts[0][1:-1] |
| 49 | + |
| 50 | + a, x, b = axb_extract(parts[0][1:-1]) |
| 51 | + |
| 52 | + coef = binom_coef(exponent) |
| 53 | + # print(bc) |
| 54 | + |
| 55 | + qa = 1 |
| 56 | + qb = 1 |
| 57 | + for i in range(exponent+1): |
| 58 | + coef[exponent-i] *= qb |
| 59 | + coef[i] *= qa |
| 60 | + qb *= b |
| 61 | + qa *= a |
| 62 | + |
| 63 | + elements = [] |
| 64 | + |
| 65 | + for i in range(exponent, -1, -1): |
| 66 | + sign = '+' if coef[i] > 0 else '-' |
| 67 | + elem_coef = abs(coef[i]) if abs(coef[i]) > 1 else '' |
| 68 | + if i > 1: |
| 69 | + elements.append('{}{}{}^{}'.format(sign, elem_coef, x, i)) |
| 70 | + elif i == 1: |
| 71 | + elements.append('{}{}{}'.format(sign, elem_coef, x)) |
| 72 | + else: |
| 73 | + elements.append('{}{}'.format(sign, elem_coef)) |
| 74 | + |
| 75 | + if elements[0][0] == '+': |
| 76 | + elements[0] = elements[0][1:] |
| 77 | + |
| 78 | + if len(elements[-1]) == 1: |
| 79 | + elements[-1] += '1' |
| 80 | + |
| 81 | + return ''.join(elements) |
| 82 | + |
| 83 | + |
| 84 | + |
| 85 | + |
| 86 | + |
| 87 | +print(expand("(2x+1)^0"), "1") |
| 88 | +print(expand("(x+1)^0"), "1") |
| 89 | +print(expand("(x+1)^1"), "x+1") |
| 90 | +print(expand("(x+1)^2"), "x^2+2x+1") |
| 91 | + |
| 92 | +print(expand("(x-1)^0"), "1") |
| 93 | +print(expand("(x-1)^1"), "x-1") |
| 94 | +print(expand("(x-1)^2"), "x^2-2x+1") |
| 95 | + |
| 96 | +print(expand("(5m+3)^4"), "625m^4+1500m^3+1350m^2+540m+81") |
| 97 | +print(expand("(2x-3)^3"), "8x^3-36x^2+54x-27") |
| 98 | +print(expand("(7x-7)^0"), "1") |
| 99 | + |
| 100 | +print(expand("(-5m+3)^4"), "625m^4-1500m^3+1350m^2-540m+81") |
| 101 | +print(expand("(-2k-3)^3"), "-8k^3-36k^2-54k-27") |
| 102 | +print(expand("(-7x-7)^0"), "1") |
0 commit comments