gendata_cocsep.h (4188B)
1 STATIC size_t gendata_cocsep(unsigned char *, uint64_t *, cube_t *); 2 STATIC uint32_t gendata_cocsep_dfs(cocsep_dfs_arg_t [static 1]); 3 STATIC void getdistribution_cocsep( 4 const uint32_t [static COCSEP_TABLESIZE], uint64_t [static 21]); 5 6 STATIC_INLINE bool gendata_cocsep_get_visited( 7 const uint8_t [static COCSEP_VISITEDSIZE], int64_t); 8 STATIC_INLINE void gendata_cocsep_set_visited( 9 uint8_t [static COCSEP_VISITEDSIZE], int64_t); 10 11 STATIC_INLINE int8_t get_h48_cdata( 12 cube_t, const uint32_t [static COCSEP_TABLESIZE], uint32_t *); 13 14 STATIC size_t 15 gendata_cocsep( 16 unsigned char *buf, 17 uint64_t *selfsim, 18 cube_t *rep 19 ) 20 { 21 uint32_t *buf32, cc; 22 uint16_t n; 23 uint8_t i, visited[COCSEP_VISITEDSIZE]; 24 tableinfo_t info; 25 cocsep_dfs_arg_t arg; 26 27 if (buf == NULL) 28 goto gendata_cocsep_return_size; 29 30 memset(buf, 0xFF, COCSEP_FULLSIZE); 31 buf32 = (uint32_t *)(buf + INFOSIZE); 32 if (selfsim != NULL) 33 memset(selfsim, 0, sizeof(uint64_t) * COCSEP_CLASSES); 34 35 info = (tableinfo_t) { 36 .solver = "cocsep data for h48", 37 .type = TABLETYPE_SPECIAL, 38 .infosize = INFOSIZE, 39 .fullsize = COCSEP_FULLSIZE, 40 .hash = 0, /* TODO */ 41 .entries = COCSEP_TABLESIZE, 42 .classes = COCSEP_CLASSES, 43 .bits = 32, 44 .base = 0, 45 .maxvalue = 9, 46 .next = 0 47 }; 48 arg = (cocsep_dfs_arg_t) { 49 .cube = SOLVED_CUBE, 50 .n = &n, 51 .buf32 = buf32, 52 .visited = visited, 53 .selfsim = selfsim, 54 .rep = rep 55 }; 56 for (i = 0, n = 0, cc = 0; i < 10; i++) { 57 memset(visited, 0, COCSEP_VISITEDSIZE); 58 arg.depth = 0; 59 arg.maxdepth = i; 60 cc = gendata_cocsep_dfs(&arg); 61 info.distribution[i] = cc; 62 } 63 64 writetableinfo(&info, COCSEP_FULLSIZE, buf); 65 66 DBG_ASSERT(n == COCSEP_CLASSES, 0, 67 "cocsep: computed %" PRIu16 " symmetry classes, " 68 "expected %zu\n", n, COCSEP_CLASSES); 69 70 LOG("[H48 gendata] cocsep data computed\n"); 71 72 /* The following output is just noise 73 74 LOG("Symmetry classes: %" PRIu32 "\n", COCSEP_CLASSES); 75 LOG("Pruning value distribution:\n"); 76 for (j = 0; j < 10; j++) 77 LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, info.distribution[j]); 78 */ 79 80 gendata_cocsep_return_size: 81 return COCSEP_FULLSIZE; 82 } 83 84 STATIC uint32_t 85 gendata_cocsep_dfs(cocsep_dfs_arg_t arg[static 1]) 86 { 87 uint8_t m; 88 uint32_t cc, class, ttrep, depth, olddepth, tinv; 89 uint64_t t; 90 int64_t i, j; 91 cube_t d; 92 cocsep_dfs_arg_t nextarg; 93 94 i = coord_cocsep(arg->cube); 95 olddepth = (uint8_t)(arg->buf32[i] & 0xFF); 96 if (olddepth < arg->depth || 97 gendata_cocsep_get_visited(arg->visited, i)) 98 return 0; 99 gendata_cocsep_set_visited(arg->visited, i); 100 101 if (arg->depth == arg->maxdepth) { 102 if ((arg->buf32[i] & 0xFF) != 0xFF) 103 return 0; 104 105 if (arg->rep != NULL) 106 arg->rep[*arg->n] = arg->cube; 107 for (t = 0, cc = 0; t < NTRANS; t++) { 108 d = transform_corners(arg->cube, t); 109 j = coord_cocsep(d); 110 if (i == j && arg->selfsim != NULL) 111 arg->selfsim[*arg->n] |= UINT64_C(1) << t; 112 if (COCLASS(arg->buf32[j]) != UINT32_C(0xFFFF)) 113 continue; 114 gendata_cocsep_set_visited(arg->visited, j); 115 tinv = inverse_trans(t); 116 olddepth = arg->buf32[j] & 0xFF; 117 cc += olddepth == 0xFF; 118 119 class = (uint32_t)(*arg->n) << UINT32_C(16); 120 ttrep = (uint32_t)tinv << UINT32_C(8); 121 depth = (uint32_t)arg->depth; 122 arg->buf32[j] = class | ttrep | depth; 123 } 124 (*arg->n)++; 125 126 return cc; 127 } 128 129 nextarg = *arg; 130 nextarg.depth++; 131 for (m = 0, cc = 0; m < 18; m++) { 132 nextarg.cube = move(arg->cube, m); 133 cc += gendata_cocsep_dfs(&nextarg); 134 } 135 136 return cc; 137 } 138 139 STATIC void 140 getdistribution_cocsep( 141 const uint32_t table[static COCSEP_TABLESIZE], 142 uint64_t distr[static 21] 143 ) 144 { 145 size_t i; 146 147 memset(distr, 0, 21 * sizeof(uint64_t)); 148 149 for (i = 0; i < COCSEP_TABLESIZE; i++) 150 distr[CBOUND(table[i])]++; 151 } 152 153 STATIC_INLINE bool 154 gendata_cocsep_get_visited( 155 const uint8_t a[static COCSEP_VISITEDSIZE], 156 int64_t i 157 ) 158 { 159 return a[VISITED_IND(i)] & VISITED_MASK(i); 160 } 161 162 STATIC_INLINE void 163 gendata_cocsep_set_visited( 164 uint8_t a[static COCSEP_VISITEDSIZE], 165 int64_t i 166 ) 167 { 168 a[VISITED_IND(i)] |= VISITED_MASK(i); 169 } 170 171 STATIC_INLINE int8_t 172 get_h48_cdata( 173 cube_t cube, 174 const uint32_t cocsepdata[static COCSEP_TABLESIZE], 175 uint32_t *cdata 176 ) 177 { 178 int64_t coord; 179 180 coord = coord_cocsep(cube); 181 *cdata = cocsepdata[coord]; 182 183 return CBOUND(*cdata); 184 }