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 (3819B)


      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 
      4 STATIC_INLINE bool gendata_cocsep_get_visited(
      5     const uint8_t [static COCSEP_VISITEDSIZE], uint64_t);
      6 STATIC_INLINE void gendata_cocsep_set_visited(
      7     uint8_t [static COCSEP_VISITEDSIZE], uint64_t);
      8 
      9 STATIC_INLINE int8_t get_h48_cdata(
     10     cube_t, const uint32_t [static 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[static 1])
     83 {
     84 	uint8_t m;
     85 	uint32_t cc, class, ttrep, depth, olddepth, tinv;
     86 	uint64_t t;
     87 	uint64_t i, j;
     88 	cube_t d;
     89 	cocsep_dfs_arg_t nextarg;
     90 
     91 	i = coord_cocsep(arg->cube);
     92 	olddepth = (uint8_t)(arg->buf32[i] & 0xFF);
     93 	if (olddepth < arg->depth ||
     94 	    gendata_cocsep_get_visited(arg->visited, i))
     95 		return 0;
     96 	gendata_cocsep_set_visited(arg->visited, i);
     97 
     98 	if (arg->depth == arg->maxdepth) {
     99 		if ((arg->buf32[i] & 0xFF) != 0xFF)
    100 			return 0;
    101 
    102 		if (arg->rep != NULL)
    103 			arg->rep[*arg->n] = arg->cube;
    104 		for (t = 0, cc = 0; t < NTRANS; t++) {
    105 			d = transform_corners(arg->cube, t);
    106 			j = coord_cocsep(d);
    107 			if (i == j && arg->selfsim != NULL)
    108 				arg->selfsim[*arg->n] |= UINT64_C(1) << t;
    109 			if (COCLASS(arg->buf32[j]) != UINT32_C(0xFFFF))
    110 				continue;
    111 			gendata_cocsep_set_visited(arg->visited, j);
    112 			tinv = inverse_trans(t);
    113 			olddepth = arg->buf32[j] & 0xFF;
    114 			cc += olddepth == 0xFF;
    115 
    116 			class = (uint32_t)(*arg->n) << UINT32_C(16);
    117 			ttrep = (uint32_t)tinv << UINT32_C(8);
    118 			depth = (uint32_t)arg->depth;
    119 			arg->buf32[j] = class | ttrep | depth;
    120 		}
    121 		(*arg->n)++;
    122 
    123 		return cc;
    124 	}
    125 
    126 	nextarg = *arg;
    127 	nextarg.depth++;
    128 	for (m = 0, cc = 0; m < 18; m++) {
    129 		nextarg.cube = move(arg->cube, m);
    130 		cc += gendata_cocsep_dfs(&nextarg);
    131 	}
    132 
    133 	return cc;
    134 }
    135 
    136 STATIC_INLINE bool
    137 gendata_cocsep_get_visited(
    138 	const uint8_t a[static COCSEP_VISITEDSIZE],
    139 	uint64_t i
    140 )
    141 {
    142 	return a[VISITED_IND(i)] & VISITED_MASK(i);
    143 }
    144 
    145 STATIC_INLINE void
    146 gendata_cocsep_set_visited(
    147 	uint8_t a[static COCSEP_VISITEDSIZE],
    148 	uint64_t i
    149 )
    150 {
    151 	a[VISITED_IND(i)] |= VISITED_MASK(i);
    152 }
    153 
    154 STATIC_INLINE int8_t
    155 get_h48_cdata(
    156 	cube_t cube,
    157 	const uint32_t cocsepdata[static COCSEP_TABLESIZE],
    158 	uint32_t *cdata
    159 )
    160 {
    161 	uint64_t coord;
    162 
    163 	coord = coord_cocsep(cube);
    164 	*cdata = cocsepdata[coord];
    165 
    166 	return CBOUND(*cdata);
    167 }