Skip to content

Instantly share code, notes, and snippets.

@ihaque
Created August 27, 2021 19:42
Show Gist options
  • Save ihaque/ee2f6de2091b5755219d8533b9bdfd15 to your computer and use it in GitHub Desktop.
Save ihaque/ee2f6de2091b5755219d8533b9bdfd15 to your computer and use it in GitHub Desktop.
Generate set of 64-bit FPs with fully unique pairwise Tanimotos
0x831A122F5DED0F74
0xF1E6F872274DB4B4
0x8940578CC91025A7
0x5DFE2CABD588AB8A
0xF17DA5DF5A7438AB
0x8F97D17115314C0D
0xAFCF937513811F3B
0xDE69E942303BA44D
0x64D37E0B37C3B362
0x09171FE07590059D
0x721B780423404B05
0xD9EDEBF5C845228D
0x1FF6DFEA53D3D91D
0x01105E18B5017860
0x00414301D8203AC1
0x66DE9C6AF591BD0D
0xFD6FF4DF2FFF3EFB
# Uses int.bit_count from Python 3.10rc1
from fractions import Fraction
from random import randint, seed
from sys import stdout
from time import time
def rand64():
return randint(0,0xFFFFFFFFFFFFFFFF)
def tanimoto(a,b):
return Fraction((a&b).bit_count(), (a|b).bit_count())
if __name__ == '__main__':
start = time()
seed()
fps = [rand64(), rand64()]
all_tans = {tanimoto(fps[0], fps[1])}
tried_since_pass = 0
while True:
new = rand64()
new_tans = {tanimoto(new, x) for x in fps}
# If all Tanimotos in this row are unique and do not overlap with
# previously calculated Tanimotos, then the full matrix will continue
# to be unique
if (len(new_tans) == len(fps)) and len(new_tans & all_tans) == 0:
fps.append(new)
all_tans = all_tans | new_tans
print('\nTook %d tries to add, now at %d, %d tans, et %.1fs' %
(tried_since_pass, len(fps), len(all_tans), time() - start))
for fp in fps:
print('0x%016X' % fp)
assert(len(all_tans) == (len(fps) * (len(fps)-1))/2)
tried_since_pass = 0
else:
tried_since_pass += 1
if tried_since_pass % 10000 == 0:
stdout.write('.')
stdout.flush()
import sys
from fractions import Fraction
fps = []
tans = set()
def tanimoto(a,b):
return Fraction((a & b).bit_count() , (a | b).bit_count())
for line in sys.stdin:
num = int(line.rstrip(),16)
print('0x%016X' % num)
assert num not in fps
fps.append(num)
for i in fps:
for j in fps:
if i == j:
continue
tan = tanimoto(i,j)
assert tan not in tans
tans.add(tan)
print('Pass! %d Tanimotos, %d FPs' % (len(tans), len(fps)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment