from __future__ import print_function
def solve(watermarks, patterns):
"""Given patterns and watermarks, find all possible mappings
and print possible encodings."""
# Each pattern potentially generates multiple mappings.
# When we have two lists of mappings, we generate
# a combined list of mappings that is compatible
# with both input mappings lists.
import mapping
mappings = None
for p in patterns:
pattern_mappings = mapping.MappingSet()
# Note that we try to find mappings for this
# pattern in ALL watermarks before reconciling
# with previous mapping. This is because the
# good mapping may only be found in one watermark.
# If we start with a "bad" watermark and find
# bad mappings, then, if we reconcile immediately,
# we may come to the conclusion that there is no
# solution, when, in fact, the good mapping will
# be found if we keep looking.
for w in watermarks:
m = p.find_all_mappings(w)
if m:
pattern_mappings.extend(m)
mappings = mapping.reconcile(mappings, pattern_mappings)
# Loop over each mapping and try to apply it to all
# watermarks. If it resolve more than some threshold
# fraction of all watermarks, print the results.
threshold = 0.40
for m in mappings:
results = {}
for w in watermarks:
pv, wv, count = m.decode(w, '_')
# d = decoded message,
# count = number of unconverted values
if count / float(len(pv)) > threshold:
break
results[w] = (pv, wv)
else:
print("Possible mapping:")
for pv, wv in results.values():
_print_pair(pv, wv)
print()
def _print_pair(pv, wv):
i = 0
total_width = 0
pl = []
wl = []
max_line_width = 72
while i < len(pv):
p = repr(pv[i])[1:-1]
w = repr(wv[i])[1:-1]
width = max(len(p), len(w))
pl.append(p.ljust(width))
wl.append(w.ljust(width))
total_width += width
if total_width > max_line_width:
print(''.join(pl))
print(''.join(wl))
total_width = 0
pl = []
wl = []
i += 1
if total_width > 0:
print(''.join(pl))
print(''.join(wl))
if __name__ == "__main__":
import given
from watermark import DNAWatermark
from pattern import StringPattern
watermarks = [ DNAWatermark(s) for s in given.watermarks ]
patterns = [ StringPattern(h) for h in given.hints ]
from mapping import add_mapping
add_mapping("CCC", "-")
add_mapping("GAA", "'")
solve(watermarks, patterns)