import bounds
header_re = re.compile(r'^(\d+) into (\d+).*:.* ([\d/]+)')
+dissect_re = re.compile(r'\s+(\d+)\s+x\s+\((([\d/]+ \+ )*[\d/]+)\)')
+
+dissections = {}
+
+def find_min_frag(dissection):
+ ret = None
+ for side in dissection:
+ for count, pieces in side:
+ for piece in pieces:
+ if piece > 0:
+ if ret is None or ret > piece:
+ ret = piece
+ assert ret is not None
+ return ret
+
+def verify(n, m, dissection):
+ collections = [{}, {}]
+ total = 0
+ for count, pieces in dissection[0]:
+ assert sum(pieces) == n
+ total += count
+ for piece in pieces:
+ collections[0].setdefault(piece, 0)
+ collections[0][piece] += count
+ assert total == m
+ total = 0
+ for count, pieces in dissection[1]:
+ assert sum(pieces) == m
+ total += count
+ for piece in pieces:
+ collections[1].setdefault(piece, 0)
+ collections[1][piece] += count
+ assert total == n
+ assert collections[0] == collections[1]
def read(n,m):
best = 0
assert int(match.group(1)) == n
assert int(match.group(2)) == m
this_best = Fraction(match.group(3))
+
+ # Now read the actual dissection.
+ dissection = [[],[]]
+ for line in f.readlines():
+ match = dissect_re.match(line)
+ if match is not None:
+ count = int(match.group(1))
+ pieces = map(Fraction, match.group(2).split(" + "))
+ length = sum(pieces)
+ if length == n:
+ dissection[0].append((count, pieces))
+ elif length == m:
+ dissection[1].append((count, pieces))
+ else:
+ assert False, "wrong length"
+ verify(n, m, dissection)
+ assert find_min_frag(dissection) == this_best
+ dissections[(n,m)] = dissection
+
if this_best > best:
best = this_best
best_nature = nature