from math import sqrt, ceil, log2 from sys import exit data = [] def fill(num, count, bit): if (bit == 9 or bit == 8) and count > 3: return if count == 5: mask = (1<<6)-1 if (((num & (num>>5)) | (num & (num>>10)) | ((num>>5) & (num>>10))) & mask) != 0: return data.append(num) return if bit == -1: return fill(num, count, bit-1) fill(num | (1<<bit), count+1, bit-1) fill(0, 0, 14) def hash_func(data, pow2=True): class DoesNotFit(Exception): pass #controlla che elementi nella stessa posizione non siano settati def check(l, r): for a, b in zip(l, r): if (a&b)==1: return False return True #calcolo dimensione minima size = max(ceil(sqrt(max(data))), len(data)) if pow2: size = 1<<ceil(log2(size)) #procedo per tentativi while True: try: square = [[0]*size for i in range(size)] rowcounts = [0] * size #tabella da comprimere for c in data: square[c//size][c%size] = 1 rowcounts[c//size]+=1 most_frequent_row_order = reversed(sorted(zip(rowcounts, range(size)))) #shift relativo ad ogni riga shifts = [0]*size #tabella compressa in una riga C = [0]*size #cerco di ruotare ogni riga in modo che non ci siano duplicati sulle colonne for _, r in most_frequent_row_order: tmp = square[r] #ruoto finché non trovo una rotazione che vada bene o abbia fatto un giro completo while not check(C, tmp) and shifts[r] < size: shifts[r] += 1 tmp = tmp[-1:]+tmp[:-1] #Se ho compiuto un giro completo non posso sistemare le righe if shifts[r] == size: raise DoesNotFit #marko le posizioni occupate dalla riga corrente ruotata C = list(map(sum, zip(C, tmp))) return size, shifts except DoesNotFit: pass #ritento con una dimensione più grande if pow2: size = size << 1 else: size += 1 def output_c_hash_func(data, prefix="", pow2=True): size, shifts = hash_func(data, pow2) tsize = prefix+"SIZE" def tshifts(n): return prefix+"SHIFTS["+str(n)+"]" def ttable(n): return prefix+"TABLE["+str(n)+"]" print("#define", tsize, size) print("int", tshifts(size), "= {", end="") it = iter(shifts) print(next(it), end="") for c in it: print(",", c, end="") print("};") print("int", ttable(size), ";") print("#define", prefix+"lookup(i)", ttable("((i)+"+tshifts("(i)/"+tsize)+")%"+tsize)) output_c_hash_func(data, "HT_", False)
Standard input is empty
#define HT_SIZE 226 int HT_SHIFTS[226] = {0, 0, 0, 0, 0, 1, 0, 2, 11, 0, 2, 12, 17, 2, 69, 37, 41, 100, 0, 0, 1, 0, 1, 54, 22, 42, 37, 38, 0, 114, 91, 135, 110, 0, 0, 0, 0, 2, 0, 0, 109, 5, 0, 2, 0, 0, 41, 66, 1, 64, 35, 0, 0, 0, 0, 0, 0, 9, 16, 0, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 40, 0, 0, 0, 0, 4, 6, 0, 0, 0, 1, 6, 0, 0, 6, 10, 0, 0, 8, 12, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 28, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int HT_TABLE[226] ; #define HT_lookup(i) HT_TABLE[((i)+HT_SHIFTS[(i)/HT_SIZE])%HT_SIZE]