mirror of
https://git.cs.ou.nl/joshua.moerman/mealy-decompose.git
synced 2025-04-29 17:57:44 +02:00
101 lines
2 KiB
Python
101 lines
2 KiB
Python
from math import prod
|
|
|
|
# bounds
|
|
N = 99999
|
|
C = 16
|
|
|
|
|
|
# precondition k <= n
|
|
def all_partitions_(n, k):
|
|
if n == 0:
|
|
return [[]]
|
|
|
|
acc = []
|
|
for j in range(1, k + 1):
|
|
ps = all_partitions_(n - j, min(n - j, j))
|
|
acc.extend([[j] + p for p in ps])
|
|
|
|
return acc
|
|
|
|
|
|
def all_partitions(n):
|
|
return all_partitions_(n, n)
|
|
|
|
|
|
def highest_product(n):
|
|
ps = all_partitions(n)
|
|
|
|
highest_prod = {}
|
|
|
|
for p in ps:
|
|
if len(p) > C:
|
|
continue
|
|
|
|
v = prod(p)
|
|
if len(p) not in highest_prod:
|
|
highest_prod[len(p)] = v
|
|
else:
|
|
if v > highest_prod[len(p)]:
|
|
highest_prod[len(p)] = v
|
|
|
|
return highest_prod
|
|
|
|
|
|
def tabulate(upper):
|
|
highest_n_per_c = {}
|
|
table = {}
|
|
for s in range(1, upper + 1):
|
|
res = highest_product(s)
|
|
|
|
for c, n in res.items():
|
|
for n2 in range(highest_n_per_c.get(c, 0) + 1, min(n, N) + 1):
|
|
table[(n2, c)] = s
|
|
|
|
highest_n_per_c[c] = n
|
|
|
|
return {(n, c): s for (n, c), s in table.items() if s <= n}
|
|
|
|
|
|
def trim_tab(tab):
|
|
best_s = {}
|
|
best_c = {}
|
|
for (n, c), s in tab.items():
|
|
if n not in best_s:
|
|
best_s[n] = s
|
|
best_c[n] = c
|
|
|
|
if s < best_s[n]:
|
|
best_s[n] = s
|
|
best_c[n] = c
|
|
|
|
return {(n, c): s for (n, c), s in tab.items() if c <= best_c[n] or s <= best_s[n]}
|
|
|
|
|
|
def print_table(tab0):
|
|
tab = trim_tab(tab0)
|
|
|
|
col_width = {0: 1} | {c: len(str(c)) for (_, c) in tab.keys()}
|
|
|
|
for (n, c), s in tab.items():
|
|
col_width[0] = max(col_width[0], len(str(n)))
|
|
col_width[c] = max(col_width[c], len(str(s)))
|
|
|
|
N = max([n for (n, _) in tab.keys()])
|
|
C = max([c for (_, c) in tab.keys()])
|
|
|
|
prev_row = ''
|
|
|
|
for n in range(1, N + 1):
|
|
best = None
|
|
row = ''
|
|
for c in range(1, C + 1):
|
|
if (n, c) in tab:
|
|
row += ' ' + str(tab[(n, c)]).rjust(col_width[c])
|
|
if not best or tab[(n, c)] < best[0]:
|
|
best = (tab[(n, c)], c)
|
|
else:
|
|
row += ' ' + ''.rjust(col_width[c])
|
|
|
|
if row != prev_row:
|
|
print(str(n).rjust(col_width[0]) + ' |' + row + ' | ' + str(best))
|
|
prev_row = row
|