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

common.h (4581B)


      1 STATIC uint64_t coord_coord_generic(
      2     const coord_t [static 1], cube_t, const unsigned char *);
      3 STATIC cube_t coord_cube_generic(
      4     const coord_t [static 1], uint64_t, const unsigned char *);
      5 STATIC bool coord_isnasty_generic(
      6     const coord_t [static 1], uint64_t, const unsigned char *);
      7 STATIC size_t coord_gendata_generic(const coord_t [static 1], unsigned char *);
      8 
      9 STATIC void append_coord_name(const coord_t [static 1], char *);
     10 STATIC bool solution_lastqt_cw(const solution_moves_t [static 1]);
     11 STATIC bool coord_can_switch(const coord_t [static 1], const unsigned char *,
     12     size_t n, const uint8_t [n]);
     13 
     14 STATIC uint64_t
     15 coord_coord_generic(
     16 	const coord_t coord[static 1],
     17 	cube_t c,
     18 	const unsigned char *data
     19 )
     20 {
     21 	const unsigned char *datanoinfo;
     22 	const uint32_t *data32;
     23 	uint32_t d;
     24 	cube_t tr;
     25 
     26 	datanoinfo = data + INFOSIZE;
     27 	data32 = (const uint32_t *)datanoinfo;
     28 	d = data32[coord->sym.coord(c)];
     29 	tr = transform(c, COORD_TTREP(d));
     30 
     31 	return COORD_CLASS(d) * coord->sym.max2 + coord->sym.coord2(tr);
     32 }
     33 
     34 STATIC cube_t
     35 coord_cube_generic(
     36 	const coord_t coord[static 1],
     37 	uint64_t i,
     38 	const unsigned char *data
     39 )
     40 {
     41 	const unsigned char *datanoinfo;
     42 	const uint32_t *rep32;
     43 	cube_t c;
     44 
     45 	datanoinfo = data + INFOSIZE;
     46 	rep32 = (const uint32_t *)(datanoinfo + 4 * (size_t)coord->sym.max);
     47 	c = coord->sym.cube(rep32[i / coord->sym.max2]);
     48 
     49 	return coord->sym.merge(c, coord->sym.cube2(i % coord->sym.max2));
     50 }
     51 
     52 STATIC bool
     53 coord_isnasty_generic(
     54 	const coord_t coord[static 1],
     55 	uint64_t i,
     56 	const unsigned char *data
     57 )
     58 {
     59 	const unsigned char *datanoinfo;
     60 	const uint32_t *classttrep, *rep32;
     61 	uint32_t r;
     62 
     63 	datanoinfo = data + INFOSIZE;
     64 	classttrep = (const uint32_t *)datanoinfo;
     65 	rep32 = (const uint32_t *)(datanoinfo + 4 * (size_t)coord->sym.max);
     66 	r = rep32[i / coord->sym.max2];
     67 
     68 	return COORD_ISNASTY(classttrep[r]);
     69 }
     70 
     71 STATIC size_t
     72 coord_gendata_generic(
     73 	const coord_t coord[static 1],
     74 	unsigned char *data
     75 )
     76 {
     77 	uint64_t i, j, n, t, nasty;
     78 	unsigned char *datanoinfo;
     79 	uint32_t *classttrep, *rep;
     80 	size_t coord_datasize;
     81 	cube_t c;
     82 	tableinfo_t info;
     83 
     84 	coord_datasize = INFOSIZE + 4*(coord->sym.classes + coord->sym.max);
     85 
     86 	if (data == NULL)
     87 		return coord_datasize;
     88 
     89 	datanoinfo = data + INFOSIZE;
     90 	classttrep = (uint32_t *)datanoinfo;
     91 	rep = classttrep + coord->sym.max;
     92 	memset(data, 0xFF, coord_datasize);
     93 
     94 	info = (tableinfo_t) {
     95 		.solver = "coord data for ",
     96 		.type = TABLETYPE_SPECIAL,
     97 		.infosize = INFOSIZE,
     98 		.fullsize = coord_datasize,
     99 		.hash = 0,
    100 		.entries = coord->sym.classes + coord->sym.max,
    101 		.classes = coord->sym.classes,
    102 		.bits = 32,
    103 		.base = 0,
    104 		.maxvalue = 0,
    105 		.next = 0
    106 	};
    107 	append_coord_name(coord, info.solver);
    108 
    109 	for (i = 0, n = 0; i < coord->sym.max; i++) {
    110 		if (classttrep[i] != 0xFFFFFFFF)
    111 			continue;
    112 
    113 		c = coord->sym.cube(i);
    114 		for (t = 1, nasty = 0; t < NTRANS && !nasty; t++) {
    115 			if (!((UINT64_C(1) << t) & coord->trans_mask))
    116 				continue;
    117 
    118 			nasty = i == coord->sym.coord(transform(c, t));
    119 		}
    120 
    121 		for (t = 0; t < NTRANS; t++) {
    122 			if (!((UINT64_C(1) << t) & coord->trans_mask))
    123 				continue;
    124 
    125 			j = coord->sym.coord(transform(c, t));
    126 			classttrep[j] =
    127 			    (n << COORD_CLASS_SHIFT) |
    128 			    (nasty << COORD_ISNASTY_SHIFT) |
    129 			    (inverse_trans(t) << COORD_TTREP_SHIFT);
    130 		}
    131 		rep[n++] = i;
    132 	}
    133 
    134 	writetableinfo(&info, coord_datasize, data);
    135 
    136 	DBG_ASSERT(n == coord->sym.classes, SIZE_MAX,
    137 	    "%s coordinate data: computed %" PRIu64 " classes, "
    138 	    "expected %" PRIu64 "\n", coord->name, n, coord->sym.classes);
    139 
    140 	return coord_datasize;
    141 }
    142 
    143 STATIC void
    144 append_coord_name(const coord_t coord[static 1], char *str)
    145 {
    146 	int i, j;
    147 
    148 	i = 0;
    149 	j = strlen(str);
    150 	while (coord->name[i]) str[j++] = coord->name[i++];
    151 
    152 	str[j] = '\0';
    153 }
    154 
    155 STATIC bool
    156 solution_lastqt_cw(const solution_moves_t s[static 1])
    157 {
    158 	return are_lastmoves_singlecw(s->nmoves, s->moves) &&
    159 	    are_lastmoves_singlecw(s->npremoves, s->premoves);
    160 }
    161 
    162 STATIC bool
    163 coord_can_switch(
    164 	const coord_t coord[static 1],
    165 	const unsigned char *data,
    166 	size_t n,
    167 	const uint8_t moves[n]
    168 )
    169 {
    170 	/*
    171 	This function checks that the last move (or two moves, if parallel)
    172 	have a non-trivial effect on the coordinate of the solved cube. This
    173 	works in general for all coordinates that have been used so far, but
    174 	in more general cases that have not been considered yet it may fail.
    175 	*/
    176 
    177 	uint64_t i;
    178 
    179 	if (n == 0)
    180 		return true;
    181 
    182 	i = coord->coord(move(SOLVED_CUBE, moves[n-1]), data);
    183 	if (i == 0)
    184 		return false;
    185 
    186 	if (n == 1 || !parallel(moves[n-1], moves[n-2]))
    187 		return true;
    188 
    189 	i = coord->coord(move(SOLVED_CUBE, moves[n-1]), data);
    190 	return i != 0;
    191 }