from collections import Counter from itertools import product def run(load,read,check): reg=load('C286_DATA.json')['target_register'];allpairs=load('C438_DATA.json')['labelled_pairs'] A=[z for z in allpairs if z['roles']==['Noah birth','Shem death']] B=[z for z in allpairs if z['roles'] in [['Flood start','Shem birth'],['Flood close','Shem birth']]] def key(row):return (row['center'],row['lower_record'],row['upper_record']) def target(source,role,rail): return [i for i,r in enumerate(reg) if r['role']==role and r.get('rail')==rail and all(r[k]==source[k] for k in ['tradition','gear','Cainan','Terah60','full430'])] mapped=[] for z in A: nd={reg[z[k]]['role']:z[k] for k in ['lower_record','upper_record']};n,s=reg[nd['Noah birth']],reg[nd['Shem death']] sb=target(n,'Shem birth',n.get('rail'));fl=target(s,'Flood close' if s.get('rail')=='companion' else 'Flood start',None) check('unique source-preserving transport '+str(key(z)),len(sb)==len(fl)==1) i,j=sb[0],fl[0] check('opposed500 preserves sum '+str(key(z)),reg[i]['center']==n['center']-500 and reg[j]['center']==s['center']+500 and reg[i]['center']+reg[j]['center']==2*z['center']) a,b=sorted([i,j],key=lambda k:reg[k]['center']) mapped.append({'source':z,'Shem_birth_record':i,'Flood_record':j,'target_key':[z['center'],a,b],'ordering_reversed':reg[i]['center']