Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from sympy import poly, symbols
- from sympy.ntheory import npartitions
- def a231599_row(n):
- """ T(n,k) is the coefficient of x^k in Product_{i=1..n} (1-x^i) """
- if n == 0:
- return [1]
- x = symbols('x')
- p = 1
- for i in range(1, n+1):
- p *= poly(1-x**i)
- p = p.all_coeffs()
- return p[::-1]
- def a026807(n, k):
- """ A026807: T(n,k) = number of partitions of n with all addends >= k """
- if k > n:
- return 0
- elif k > n/2:
- return 1
- else:
- vc = a231599_row(k-1)
- t = len(vc)
- vp_range = range(n-t, n+1)
- vp_range = vp_range[::-1] # reverse
- r = 0
- for i in range(0, t):
- r += vc[i] * npartitions(vp_range[i])
- return r
- def a026794(n, k):
- """ A026794: T(n,k) = number of partitions of n with smallest addend k """
- if n == k:
- return 1
- return a026807(n - k, k)
- def dictprodsum(pdict):
- s = 0
- for key in pdict:
- s += key * pdict[key]
- return s
- def dictunion(a_input, b):
- a = a_input.copy()
- for key in b.keys():
- if key in a:
- a[key] += b[key]
- else:
- a[key] = b[key]
- return a
- def dict_to_list(pdict):
- """ Turns a partition dict into a partition list, e.g. {4: 2, 5: 3, 6: 1} to [4, 4, 5, 5, 5, 6]. """
- plist = []
- for key in pdict:
- plist += [key for i in range(0, pdict[key])]
- return sorted(plist)
- def dict_to_valnum(pdict):
- """ Turns a partition dict into the corresponding value in A194602, e.g. {4: 1, 6: 1} to 479. """
- if pdict == {}:
- return 0
- plist = dict_to_list(pdict)
- pstr = ''
- for entry in plist:
- pstr += '0' + (entry-1) * '1'
- return int(pstr, 2)
- def valnum_to_dict(pval):
- """ Turns a value of A194602 into the corresponding partition dict, e.g. 479 to {4: 1, 6: 1}. """
- if pval == 0:
- return {}
- elif pval < 0:
- return "The number entered was negative."
- binstr = "{0:b}".format(pval) # n converted to binary string
- binarr = binstr.split('0')
- pdict = {}
- for addend_str in binarr:
- addend = len(addend_str) + 1
- if addend == 1:
- return "The number entered was not a value of A194602."
- elif addend in pdict:
- pdict[addend] += 1
- else:
- pdict[addend] = 1
- return pdict
- def dict_to_keynum(pdict_input):
- """ Turns a partition dict into the corresponding key of A194602, e.g. {4: 1, 6: 1} to 39. """
- pdict = pdict_input.copy()
- result = 0
- last_smad = 1
- while True:
- if pdict == {}:
- return result
- n = dictprodsum(pdict)
- smad = min(pdict.keys()) # smallest addend
- for i in range(last_smad, smad):
- result += a026807(n - i, i) # number of partitions of ``n`` with smallest addend equal to ``i``
- last_smad = smad
- pdict.pop(smad)
- def keynum_to_rownum(pkey):
- """ Returns the sum of the parts of the partition, i.e. the partitions row number.
- E.g. for 94 ({3: 1, 5: 2}) the row number is 13."""
- if pkey == 0:
- return 0
- row = 1
- while True:
- row += 1
- pnum = npartitions(row)
- if pkey <= pnum - 1:
- return row
- def keynum_to_smad(pkey, row):
- """ Returns the smallest addend and the number of partitions with smaller smallest addends.
- E.g. for 94 (in row 13) the smad is 3 and the n.o.p. with smaller smad is 91. """
- if pkey == 0:
- return 1
- smad = 0
- count = 0
- while count <= pkey:
- smad += 1
- nop_with_smaller_smad = count
- count += a026794(row, smad) # add n.o. partitions of ``row`` with smallest addend ``smad``
- return smad, nop_with_smaller_smad
- def keynum_to_dict(pkey):
- """ Turns a key of A194602 into the corresponding partition dict, e.g. 39 to {4: 1, 6: 1}. """
- if pkey == 0:
- return {}
- row = keynum_to_rownum(pkey)
- (smad, nop_with_smaller_smad) = keynum_to_smad(pkey, row)
- # partition to be found is ``pos``-th among partitions of ``row`` with smallest addend ``smad``, counted from 1
- pos = pkey - nop_with_smaller_smad + 1
- # step upwards until all addends ``smad`` are gone, recursively use this function on that partitions key number
- rem = 1
- while a026794(row - rem*smad, smad) > pos: # while a removed addend ``smad`` was not the last one
- rem += 1
- result1 = {smad: rem} # the ``rem`` addends ``smad`` that were removed become part of the result to be returned
- new_row = row - rem*smad # the row of the new partition with the smallest addends removed
- key_count = 0
- for smaller in range(1, smad):
- key_count += a026794(new_row, smaller)
- new_pkey = key_count + pos - 1
- result2 = keynum_to_dict(new_pkey)
- return dictunion(result1, result2)
- def keynum_to_valnum(pkey):
- """ Turns a key of A194602 into the corresponding value, e.g. 39 to 479. """
- return dict_to_valnum(keynum_to_dict(pkey))
- def valnum_to_keynum(pval):
- """ Turns a value of A194602 into the corresponding key, e.g. 479 to 39. """
- return dict_to_keynum(valnum_to_dict(pval))
Add Comment
Please, Sign In to add comment