fork(3) download
  1. from math import sqrt, ceil, log2
  2. from sys import exit
  3. data = []
  4. def fill(num, count, bit):
  5. if (bit == 9 or bit == 8) and count > 3:
  6. return
  7. if count == 5:
  8. mask = (1<<6)-1
  9. if (((num & (num>>5)) | (num & (num>>10)) | ((num>>5) & (num>>10))) & mask) != 0:
  10. return
  11. data.append(num)
  12. return
  13. if bit == -1:
  14. return
  15. fill(num, count, bit-1)
  16. fill(num | (1<<bit), count+1, bit-1)
  17.  
  18. fill(0, 0, 14)
  19.  
  20.  
  21.  
  22. def hash_func(data, pow2=True):
  23. class DoesNotFit(Exception):
  24. pass
  25.  
  26. #controlla che elementi nella stessa posizione non siano settati
  27. def check(l, r):
  28. for a, b in zip(l, r):
  29. if (a&b)==1:
  30. return False
  31. return True
  32.  
  33. #calcolo dimensione minima
  34. size = max(ceil(sqrt(max(data))), len(data))
  35. if pow2:
  36. size = 1<<ceil(log2(size))
  37.  
  38. #procedo per tentativi
  39. while True:
  40. try:
  41.  
  42. square = [[0]*size for i in range(size)]
  43. rowcounts = [0] * size
  44.  
  45. #tabella da comprimere
  46. for c in data:
  47. square[c//size][c%size] = 1
  48. rowcounts[c//size]+=1
  49.  
  50. most_frequent_row_order = reversed(sorted(zip(rowcounts, range(size))))
  51.  
  52. #shift relativo ad ogni riga
  53. shifts = [0]*size
  54.  
  55. #tabella compressa in una riga
  56. C = [0]*size
  57.  
  58. #cerco di ruotare ogni riga in modo che non ci siano duplicati sulle colonne
  59. for _, r in most_frequent_row_order:
  60. tmp = square[r]
  61. #ruoto finché non trovo una rotazione che vada bene o abbia fatto un giro completo
  62. while not check(C, tmp) and shifts[r] < size:
  63. shifts[r] += 1
  64. tmp = tmp[-1:]+tmp[:-1]
  65. #Se ho compiuto un giro completo non posso sistemare le righe
  66. if shifts[r] == size:
  67. raise DoesNotFit
  68. #marko le posizioni occupate dalla riga corrente ruotata
  69. C = list(map(sum, zip(C, tmp)))
  70. return size, shifts
  71. except DoesNotFit:
  72. pass
  73.  
  74. #ritento con una dimensione più grande
  75. if pow2:
  76. size = size << 1
  77. else:
  78. size += 1
  79.  
  80. def output_c_hash_func(data, prefix="", pow2=True):
  81. size, shifts = hash_func(data, pow2)
  82. tsize = prefix+"SIZE"
  83. def tshifts(n):
  84. return prefix+"SHIFTS["+str(n)+"]"
  85. def ttable(n):
  86. return prefix+"TABLE["+str(n)+"]"
  87. print("#define", tsize, size)
  88. print("int", tshifts(size), "= {", end="")
  89. it = iter(shifts)
  90. print(next(it), end="")
  91. for c in it:
  92. print(",", c, end="")
  93. print("};")
  94. print("int", ttable(size), ";")
  95. print("#define", prefix+"lookup(i)", ttable("((i)+"+tshifts("(i)/"+tsize)+")%"+tsize))
  96.  
  97. output_c_hash_func(data, "HT_", False)
Success #stdin #stdout 0.06s 27728KB
stdin
Standard input is empty
stdout
#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]