nissy-core

The "engine" of nissy, including the H48 optimal solver.
git clone https://git.tronto.net/nissy-core
Download | Log | Files | Refs | README | LICENSE

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 }