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