normalized english targeted IoC

This commit is contained in:
relikd
2021-01-23 20:07:19 +01:00
parent 3762fe0946
commit b2b6809920
12 changed files with 2269 additions and 1118 deletions

View File

@@ -22,9 +22,11 @@ class InterruptDB(object):
self.iguess = SearchInterrupt(data, interrupt)
self.irp_count = len(self.iguess.stops)
def make(self, keylen):
def make(self, dbname, name, keylen):
def fn(x):
return Probability.IC_w_keylen(x, keylen)
return Probability.target_diff(x, keylen) # used in db_norm
# return Probability.IC_w_keylen(x, keylen) # used in db_high
if keylen == 0:
keylen = 1
score, skips = fn(self.iguess.join()), [[]] # without interrupts
@@ -33,19 +35,18 @@ class InterruptDB(object):
# score, skips = self.iguess.genetic(fn, topDown=False, maxdepth=4)
for i, interrupts in enumerate(skips):
skips[i] = self.iguess.to_occurrence_index(interrupts)
for nums in skips:
self.write(
name, score, self.irp, self.irp_count, keylen, nums, dbname)
return score, skips
def make_keylength(self, name, keylen, dbname='db_main'):
score, interrupts = self.make(keylen)
for nums in interrupts:
self.write(name, score, self.irp, self.irp_count, keylen, nums, dbname)
return score, interrupts
def find_secondary(self, name, keylen, threshold, dbname='db_main'):
def make_secondary(self, dbname, name, keylen, threshold):
scores = []
def fn(x):
score = Probability.IC_w_keylen(x, keylen)
score = Probability.target_diff(x, keylen) # used in db_norm
# score = Probability.IC_w_keylen(x, keylen) # used in db_high
if score >= threshold:
scores.append(score)
return 1
@@ -59,11 +60,12 @@ class InterruptDB(object):
# exclude best results, as they are already present in the main db
filtered = [x for x in ret if x[0] < bestscore]
for score, nums in filtered:
self.write(name, score, self.irp, self.irp_count, keylen, nums, dbname)
self.write(
name, score, self.irp, self.irp_count, keylen, nums, dbname)
return len(filtered)
@staticmethod
def load(dbname='db_main'):
def load(dbname):
if not os.path.isfile(f'InterruptDB/{dbname}.txt'):
return {}
ret = {}
@@ -142,11 +144,11 @@ class InterruptIndices(object):
#########################################
class InterruptToWeb(object):
def __init__(self, template):
def __init__(self, dbname, template='InterruptDB/template.html'):
self.template = template
self.indices = InterruptIndices()
self.scores = {}
db = InterruptDB.load()
db = InterruptDB.load(dbname)
for k, v in db.items():
for irpc, score, irp, kl, nums in v:
if k not in self.scores:
@@ -167,7 +169,10 @@ class InterruptToWeb(object):
trh = '<tr class="rotate"><th></th>'
trtotal = '<tr class="small"><th>Total</th>'
trd = [f'<tr><th>{x}</th>' for x in RUNES]
del_row = [True] * 29
for name in FILES_ALL:
if name not in self.scores:
continue
total = self.indices.total(name)
trh += f'<th><div>{name}</div></th>'
trtotal += f'<td>{total}</td>'
@@ -176,6 +181,7 @@ class InterruptToWeb(object):
if not scrs:
trd[i] += '<td></td>'
continue
del_row[i] = False
worst_irpc = min([x[1] for x in scrs])
if worst_irpc == 0:
if max([x[1] for x in scrs]) != 0:
@@ -188,23 +194,28 @@ class InterruptToWeb(object):
trtotal += '</tr>\n'
for i in range(29):
trd[i] += '</tr>\n'
if del_row[i]:
trd[i] = ''
return f'<table>{trh}{"".join(trd)}{trtotal}</table>'
def table_interrupt(self, irp):
def table_interrupt(self, irp, pmin=1.25, pmax=1.65):
maxkl = max(len(x[irp]) for x in self.scores.values())
trh = '<tr class="rotate"><th></th>'
trbest = '<tr class="small"><th>best</th>'
trd = [f'<tr><th>{x}</th>' for x in range(maxkl)]
for name in FILES_ALL:
trh += f'<th><div>{name}</div></th>'
maxscore = 0
bestkl = -1
try:
klarr = self.scores[name][irp]
except KeyError:
continue
trh += f'<th><div>{name}</div></th>'
for kl, (score, _) in enumerate(klarr):
trd[kl] += f'<td{self.cls(score, 1.25, 1.65)}>{score:.2f}</td>'
if score < 0:
trd[kl] += f'<td{self.cls(0)}></td>'
else:
trd[kl] += f'<td{self.cls(score, pmin, pmax)}>{score:.2f}</td>'
if score > maxscore:
maxscore = score
bestkl = kl
@@ -215,18 +226,20 @@ class InterruptToWeb(object):
trd[i] += '</tr>\n'
return f'<table>{trh}{"".join(trd[1:])}{trbest}</table>'
def make(self, outfile, template='InterruptDB/template.html'):
def make(self, outfile, pmin=1.25, pmax=1.65):
with open(self.template, 'r') as f:
html = f.read()
nav = ''
for i, r in enumerate(RUNES):
nav += f'<a href="#tb-i{i}">{r}</a>\n'
html = html.replace('__NAVIGATION__', nav)
html = html.replace('__TAB_RELIABLE__', self.table_reliable())
txt = ''
for i in range(29):
has_entries = any(True for x in self.scores.values() if x[i])
if not has_entries:
continue
nav += f'<a href="#tb-i{i}">{RUNES[i]}</a>\n'
txt += f'<h3 id="tb-i{i}">Interrupt {i}: <b>{RUNES[i]}</b></h3>'
txt += self.table_interrupt(i)
txt += self.table_interrupt(i, pmin, pmax)
html = html.replace('__NAVIGATION__', nav)
html = html.replace('__TAB_RELIABLE__', self.table_reliable())
html = html.replace('__INTERRUPT_TABLES__', txt)
with open(outfile, 'w') as f:
f.write(html)
@@ -241,7 +254,8 @@ def create_initial_db(dbname, minkl=1, maxkl=32, max_irp=20, irpset=range(29)):
oldValues = {k: set((a, b, c) for a, _, b, c, _ in v)
for k, v in oldDB.items()}
for irp in irpset: # interrupt rune index
for name in FILES_UNSOLVED: # filename
# for name in FILES_UNSOLVED:
for name in FILES_ALL:
fname = f'pages/{name}.txt'
data = load_indices(fname, irp, maxinterrupt=max_irp)
db = InterruptDB(data, irp)
@@ -250,12 +264,12 @@ def create_initial_db(dbname, minkl=1, maxkl=32, max_irp=20, irpset=range(29)):
if (db.irp_count, irp, keylen) in oldValues.get(name, []):
print(f'{keylen}: skipped.')
continue
score, interrupts = db.make_keylength(name, keylen, dbname)
score, interrupts = db.make(dbname, name, keylen)
print(f'{keylen}: {score:.4f}, solutions: {len(interrupts)}')
def find_secondary_solutions(dbname, max_irp=20, threshold=1.4):
oldDB = InterruptDB.load()
def find_secondary_solutions(db_in, db_out, threshold=0.75, max_irp=20):
oldDB = InterruptDB.load(db_in)
search_set = set()
for name, arr in oldDB.items():
if name not in FILES_UNSOLVED:
@@ -270,12 +284,14 @@ def find_secondary_solutions(dbname, max_irp=20, threshold=1.4):
print('load:', fname, 'interrupt:', irp, 'keylen:', kl)
data = load_indices(fname, irp, maxinterrupt=max_irp)
db = InterruptDB(data, irp)
c = db.find_secondary(name, kl, threshold,
db_path=f'InterruptDB/{dbname}.txt')
c = db.make_secondary(db_out, name, kl, threshold)
print('found', c, 'additional solutions')
if __name__ == '__main__':
# find_secondary_solutions('db_secondary')
# create_initial_db('db_main', minkl=1, maxkl=32, max_irp=20)
InterruptToWeb('InterruptDB/template.html').make('InterruptDB/index.html')
# find_secondary_solutions('db_high', 'db_high_secondary', threshold=1.4)
# find_secondary_solutions('db_norm', 'db_norm_secondary', threshold=0.55)
create_initial_db('db_norm', minkl=1, maxkl=32, max_irp=20, irpset=[0])
# InterruptToWeb('db_high').make('InterruptDB/index_high.html')
# InterruptToWeb('db_norm').make(
# 'InterruptDB/index_norm.html', pmin=0.40, pmax=0.98)