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

transform.h (10486B)


      1 #define TRANS_EDGES_ROTATION(T, c) \
      2         compose_edges(compose_edges(TRANS_CUBE_ ## T, c), \
      3         TRANS_CUBE_ ## T ## _INVERSE)
      4 #define TRANS_EDGES_MIRRORED(T, c) TRANS_EDGES_ROTATION(T, c)
      5 
      6 #define TRANS_CORNERS_ROTATION(T, c) \
      7         compose_corners(compose_corners(TRANS_CUBE_ ## T, c), \
      8         TRANS_CUBE_ ## T ## _INVERSE)
      9 #define TRANS_CORNERS_MIRRORED(T, c) \
     10         invertco(compose_corners( \
     11 	compose_corners(TRANS_CUBE_ ## T, c), TRANS_CUBE_ ## T ## _INVERSE))
     12 
     13 #define TRANS_ROTATION(T, c) \
     14         compose(compose(TRANS_CUBE_ ## T, c), \
     15         TRANS_CUBE_ ## T ## _INVERSE)
     16 #define TRANS_MIRRORED(T, c) \
     17         invertco(compose(compose(TRANS_CUBE_ ## T, c), \
     18         TRANS_CUBE_ ## T ## _INVERSE))
     19 
     20 STATIC uint8_t readtrans(const char [static NISSY_SIZE_TRANSFORMATION]);
     21 STATIC void writetrans(uint8_t, char [static NISSY_SIZE_TRANSFORMATION]);
     22 
     23 STATIC cube_t transform_edges(cube_t, uint8_t);
     24 STATIC cube_t transform_corners(cube_t, uint8_t);
     25 STATIC cube_t transform(cube_t, uint8_t);
     26 STATIC oriented_cube_t applytrans(oriented_cube_t, const char *);
     27 STATIC_INLINE uint8_t inverse_trans(uint8_t);
     28 STATIC uint64_t symmetry_mask(cube_t);
     29 
     30 STATIC uint8_t
     31 readtrans(const char buf[static NISSY_SIZE_TRANSFORMATION])
     32 {
     33 	uint8_t t;
     34 
     35 	for (t = 0; t < NTRANS; t++)
     36 		if (!strncmp(buf, transstr[t], 11))
     37 			return t;
     38 
     39 	return UINT8_ERROR;
     40 }
     41 
     42 STATIC void
     43 writetrans(uint8_t t, char buf[static NISSY_SIZE_TRANSFORMATION])
     44 {
     45 	if (t >= 48)
     46 		memcpy(buf, "error trans", 11);
     47 	else
     48 		memcpy(buf, transstr[t], 11);
     49 	buf[11] = '\0';
     50 }
     51 
     52 STATIC cube_t
     53 transform_edges(cube_t c, uint8_t t)
     54 {
     55 	switch (t) {
     56 	case TRANS_UFr:
     57 		return c;
     58 	case TRANS_ULr:
     59 		return TRANS_EDGES_ROTATION(ULr, c);
     60 	case TRANS_UBr:
     61 		return TRANS_EDGES_ROTATION(UBr, c);
     62 	case TRANS_URr:
     63 		return TRANS_EDGES_ROTATION(URr, c);
     64 	case TRANS_DFr:
     65 		return TRANS_EDGES_ROTATION(DFr, c);
     66 	case TRANS_DLr:
     67 		return TRANS_EDGES_ROTATION(DLr, c);
     68 	case TRANS_DBr:
     69 		return TRANS_EDGES_ROTATION(DBr, c);
     70 	case TRANS_DRr:
     71 		return TRANS_EDGES_ROTATION(DRr, c);
     72 	case TRANS_RUr:
     73 		return TRANS_EDGES_ROTATION(RUr, c);
     74 	case TRANS_RFr:
     75 		return TRANS_EDGES_ROTATION(RFr, c);
     76 	case TRANS_RDr:
     77 		return TRANS_EDGES_ROTATION(RDr, c);
     78 	case TRANS_RBr:
     79 		return TRANS_EDGES_ROTATION(RBr, c);
     80 	case TRANS_LUr:
     81 		return TRANS_EDGES_ROTATION(LUr, c);
     82 	case TRANS_LFr:
     83 		return TRANS_EDGES_ROTATION(LFr, c);
     84 	case TRANS_LDr:
     85 		return TRANS_EDGES_ROTATION(LDr, c);
     86 	case TRANS_LBr:
     87 		return TRANS_EDGES_ROTATION(LBr, c);
     88 	case TRANS_FUr:
     89 		return TRANS_EDGES_ROTATION(FUr, c);
     90 	case TRANS_FRr:
     91 		return TRANS_EDGES_ROTATION(FRr, c);
     92 	case TRANS_FDr:
     93 		return TRANS_EDGES_ROTATION(FDr, c);
     94 	case TRANS_FLr:
     95 		return TRANS_EDGES_ROTATION(FLr, c);
     96 	case TRANS_BUr:
     97 		return TRANS_EDGES_ROTATION(BUr, c);
     98 	case TRANS_BRr:
     99 		return TRANS_EDGES_ROTATION(BRr, c);
    100 	case TRANS_BDr:
    101 		return TRANS_EDGES_ROTATION(BDr, c);
    102 	case TRANS_BLr:
    103 		return TRANS_EDGES_ROTATION(BLr, c);
    104 	case TRANS_UFm:
    105 		return TRANS_EDGES_MIRRORED(UFm, c);
    106 	case TRANS_ULm:
    107 		return TRANS_EDGES_MIRRORED(ULm, c);
    108 	case TRANS_UBm:
    109 		return TRANS_EDGES_MIRRORED(UBm, c);
    110 	case TRANS_URm:
    111 		return TRANS_EDGES_MIRRORED(URm, c);
    112 	case TRANS_DFm:
    113 		return TRANS_EDGES_MIRRORED(DFm, c);
    114 	case TRANS_DLm:
    115 		return TRANS_EDGES_MIRRORED(DLm, c);
    116 	case TRANS_DBm:
    117 		return TRANS_EDGES_MIRRORED(DBm, c);
    118 	case TRANS_DRm:
    119 		return TRANS_EDGES_MIRRORED(DRm, c);
    120 	case TRANS_RUm:
    121 		return TRANS_EDGES_MIRRORED(RUm, c);
    122 	case TRANS_RFm:
    123 		return TRANS_EDGES_MIRRORED(RFm, c);
    124 	case TRANS_RDm:
    125 		return TRANS_EDGES_MIRRORED(RDm, c);
    126 	case TRANS_RBm:
    127 		return TRANS_EDGES_MIRRORED(RBm, c);
    128 	case TRANS_LUm:
    129 		return TRANS_EDGES_MIRRORED(LUm, c);
    130 	case TRANS_LFm:
    131 		return TRANS_EDGES_MIRRORED(LFm, c);
    132 	case TRANS_LDm:
    133 		return TRANS_EDGES_MIRRORED(LDm, c);
    134 	case TRANS_LBm:
    135 		return TRANS_EDGES_MIRRORED(LBm, c);
    136 	case TRANS_FUm:
    137 		return TRANS_EDGES_MIRRORED(FUm, c);
    138 	case TRANS_FRm:
    139 		return TRANS_EDGES_MIRRORED(FRm, c);
    140 	case TRANS_FDm:
    141 		return TRANS_EDGES_MIRRORED(FDm, c);
    142 	case TRANS_FLm:
    143 		return TRANS_EDGES_MIRRORED(FLm, c);
    144 	case TRANS_BUm:
    145 		return TRANS_EDGES_MIRRORED(BUm, c);
    146 	case TRANS_BRm:
    147 		return TRANS_EDGES_MIRRORED(BRm, c);
    148 	case TRANS_BDm:
    149 		return TRANS_EDGES_MIRRORED(BDm, c);
    150 	case TRANS_BLm:
    151 		return TRANS_EDGES_MIRRORED(BLm, c);
    152 	default:
    153 		LOG("transform error: unknown transformation %" PRIu8 "\n", t);
    154 		return ZERO_CUBE;
    155 	}
    156 }
    157 
    158 STATIC cube_t
    159 transform_corners(cube_t c, uint8_t t)
    160 {
    161 	switch (t) {
    162 	case TRANS_UFr:
    163 		return c;
    164 	case TRANS_ULr:
    165 		return TRANS_CORNERS_ROTATION(ULr, c);
    166 	case TRANS_UBr:
    167 		return TRANS_CORNERS_ROTATION(UBr, c);
    168 	case TRANS_URr:
    169 		return TRANS_CORNERS_ROTATION(URr, c);
    170 	case TRANS_DFr:
    171 		return TRANS_CORNERS_ROTATION(DFr, c);
    172 	case TRANS_DLr:
    173 		return TRANS_CORNERS_ROTATION(DLr, c);
    174 	case TRANS_DBr:
    175 		return TRANS_CORNERS_ROTATION(DBr, c);
    176 	case TRANS_DRr:
    177 		return TRANS_CORNERS_ROTATION(DRr, c);
    178 	case TRANS_RUr:
    179 		return TRANS_CORNERS_ROTATION(RUr, c);
    180 	case TRANS_RFr:
    181 		return TRANS_CORNERS_ROTATION(RFr, c);
    182 	case TRANS_RDr:
    183 		return TRANS_CORNERS_ROTATION(RDr, c);
    184 	case TRANS_RBr:
    185 		return TRANS_CORNERS_ROTATION(RBr, c);
    186 	case TRANS_LUr:
    187 		return TRANS_CORNERS_ROTATION(LUr, c);
    188 	case TRANS_LFr:
    189 		return TRANS_CORNERS_ROTATION(LFr, c);
    190 	case TRANS_LDr:
    191 		return TRANS_CORNERS_ROTATION(LDr, c);
    192 	case TRANS_LBr:
    193 		return TRANS_CORNERS_ROTATION(LBr, c);
    194 	case TRANS_FUr:
    195 		return TRANS_CORNERS_ROTATION(FUr, c);
    196 	case TRANS_FRr:
    197 		return TRANS_CORNERS_ROTATION(FRr, c);
    198 	case TRANS_FDr:
    199 		return TRANS_CORNERS_ROTATION(FDr, c);
    200 	case TRANS_FLr:
    201 		return TRANS_CORNERS_ROTATION(FLr, c);
    202 	case TRANS_BUr:
    203 		return TRANS_CORNERS_ROTATION(BUr, c);
    204 	case TRANS_BRr:
    205 		return TRANS_CORNERS_ROTATION(BRr, c);
    206 	case TRANS_BDr:
    207 		return TRANS_CORNERS_ROTATION(BDr, c);
    208 	case TRANS_BLr:
    209 		return TRANS_CORNERS_ROTATION(BLr, c);
    210 	case TRANS_UFm:
    211 		return TRANS_CORNERS_MIRRORED(UFm, c);
    212 	case TRANS_ULm:
    213 		return TRANS_CORNERS_MIRRORED(ULm, c);
    214 	case TRANS_UBm:
    215 		return TRANS_CORNERS_MIRRORED(UBm, c);
    216 	case TRANS_URm:
    217 		return TRANS_CORNERS_MIRRORED(URm, c);
    218 	case TRANS_DFm:
    219 		return TRANS_CORNERS_MIRRORED(DFm, c);
    220 	case TRANS_DLm:
    221 		return TRANS_CORNERS_MIRRORED(DLm, c);
    222 	case TRANS_DBm:
    223 		return TRANS_CORNERS_MIRRORED(DBm, c);
    224 	case TRANS_DRm:
    225 		return TRANS_CORNERS_MIRRORED(DRm, c);
    226 	case TRANS_RUm:
    227 		return TRANS_CORNERS_MIRRORED(RUm, c);
    228 	case TRANS_RFm:
    229 		return TRANS_CORNERS_MIRRORED(RFm, c);
    230 	case TRANS_RDm:
    231 		return TRANS_CORNERS_MIRRORED(RDm, c);
    232 	case TRANS_RBm:
    233 		return TRANS_CORNERS_MIRRORED(RBm, c);
    234 	case TRANS_LUm:
    235 		return TRANS_CORNERS_MIRRORED(LUm, c);
    236 	case TRANS_LFm:
    237 		return TRANS_CORNERS_MIRRORED(LFm, c);
    238 	case TRANS_LDm:
    239 		return TRANS_CORNERS_MIRRORED(LDm, c);
    240 	case TRANS_LBm:
    241 		return TRANS_CORNERS_MIRRORED(LBm, c);
    242 	case TRANS_FUm:
    243 		return TRANS_CORNERS_MIRRORED(FUm, c);
    244 	case TRANS_FRm:
    245 		return TRANS_CORNERS_MIRRORED(FRm, c);
    246 	case TRANS_FDm:
    247 		return TRANS_CORNERS_MIRRORED(FDm, c);
    248 	case TRANS_FLm:
    249 		return TRANS_CORNERS_MIRRORED(FLm, c);
    250 	case TRANS_BUm:
    251 		return TRANS_CORNERS_MIRRORED(BUm, c);
    252 	case TRANS_BRm:
    253 		return TRANS_CORNERS_MIRRORED(BRm, c);
    254 	case TRANS_BDm:
    255 		return TRANS_CORNERS_MIRRORED(BDm, c);
    256 	case TRANS_BLm:
    257 		return TRANS_CORNERS_MIRRORED(BLm, c);
    258 	default:
    259 		LOG("transform error: unknown transformation %" PRIu8 "\n", t);
    260 		return ZERO_CUBE;
    261 	}
    262 }
    263 
    264 STATIC cube_t
    265 transform(cube_t c, uint8_t t)
    266 {
    267 	switch (t) {
    268 	case TRANS_UFr:
    269 		return c;
    270 	case TRANS_ULr:
    271 		return TRANS_ROTATION(ULr, c);
    272 	case TRANS_UBr:
    273 		return TRANS_ROTATION(UBr, c);
    274 	case TRANS_URr:
    275 		return TRANS_ROTATION(URr, c);
    276 	case TRANS_DFr:
    277 		return TRANS_ROTATION(DFr, c);
    278 	case TRANS_DLr:
    279 		return TRANS_ROTATION(DLr, c);
    280 	case TRANS_DBr:
    281 		return TRANS_ROTATION(DBr, c);
    282 	case TRANS_DRr:
    283 		return TRANS_ROTATION(DRr, c);
    284 	case TRANS_RUr:
    285 		return TRANS_ROTATION(RUr, c);
    286 	case TRANS_RFr:
    287 		return TRANS_ROTATION(RFr, c);
    288 	case TRANS_RDr:
    289 		return TRANS_ROTATION(RDr, c);
    290 	case TRANS_RBr:
    291 		return TRANS_ROTATION(RBr, c);
    292 	case TRANS_LUr:
    293 		return TRANS_ROTATION(LUr, c);
    294 	case TRANS_LFr:
    295 		return TRANS_ROTATION(LFr, c);
    296 	case TRANS_LDr:
    297 		return TRANS_ROTATION(LDr, c);
    298 	case TRANS_LBr:
    299 		return TRANS_ROTATION(LBr, c);
    300 	case TRANS_FUr:
    301 		return TRANS_ROTATION(FUr, c);
    302 	case TRANS_FRr:
    303 		return TRANS_ROTATION(FRr, c);
    304 	case TRANS_FDr:
    305 		return TRANS_ROTATION(FDr, c);
    306 	case TRANS_FLr:
    307 		return TRANS_ROTATION(FLr, c);
    308 	case TRANS_BUr:
    309 		return TRANS_ROTATION(BUr, c);
    310 	case TRANS_BRr:
    311 		return TRANS_ROTATION(BRr, c);
    312 	case TRANS_BDr:
    313 		return TRANS_ROTATION(BDr, c);
    314 	case TRANS_BLr:
    315 		return TRANS_ROTATION(BLr, c);
    316 	case TRANS_UFm:
    317 		return TRANS_MIRRORED(UFm, c);
    318 	case TRANS_ULm:
    319 		return TRANS_MIRRORED(ULm, c);
    320 	case TRANS_UBm:
    321 		return TRANS_MIRRORED(UBm, c);
    322 	case TRANS_URm:
    323 		return TRANS_MIRRORED(URm, c);
    324 	case TRANS_DFm:
    325 		return TRANS_MIRRORED(DFm, c);
    326 	case TRANS_DLm:
    327 		return TRANS_MIRRORED(DLm, c);
    328 	case TRANS_DBm:
    329 		return TRANS_MIRRORED(DBm, c);
    330 	case TRANS_DRm:
    331 		return TRANS_MIRRORED(DRm, c);
    332 	case TRANS_RUm:
    333 		return TRANS_MIRRORED(RUm, c);
    334 	case TRANS_RFm:
    335 		return TRANS_MIRRORED(RFm, c);
    336 	case TRANS_RDm:
    337 		return TRANS_MIRRORED(RDm, c);
    338 	case TRANS_RBm:
    339 		return TRANS_MIRRORED(RBm, c);
    340 	case TRANS_LUm:
    341 		return TRANS_MIRRORED(LUm, c);
    342 	case TRANS_LFm:
    343 		return TRANS_MIRRORED(LFm, c);
    344 	case TRANS_LDm:
    345 		return TRANS_MIRRORED(LDm, c);
    346 	case TRANS_LBm:
    347 		return TRANS_MIRRORED(LBm, c);
    348 	case TRANS_FUm:
    349 		return TRANS_MIRRORED(FUm, c);
    350 	case TRANS_FRm:
    351 		return TRANS_MIRRORED(FRm, c);
    352 	case TRANS_FDm:
    353 		return TRANS_MIRRORED(FDm, c);
    354 	case TRANS_FLm:
    355 		return TRANS_MIRRORED(FLm, c);
    356 	case TRANS_BUm:
    357 		return TRANS_MIRRORED(BUm, c);
    358 	case TRANS_BRm:
    359 		return TRANS_MIRRORED(BRm, c);
    360 	case TRANS_BDm:
    361 		return TRANS_MIRRORED(BDm, c);
    362 	case TRANS_BLm:
    363 		return TRANS_MIRRORED(BLm, c);
    364 	default:
    365 		return ZERO_CUBE;
    366 	}
    367 }
    368 
    369 STATIC oriented_cube_t
    370 applytrans(oriented_cube_t cube, const char *buf)
    371 {
    372 	uint8_t t;
    373 
    374 	DBG_ASSERT(isconsistent(cube), ZERO_ORIENTED_CUBE,
    375 	    "transformation error: inconsistent cube\n");
    376 
    377 	t = readtrans(buf);
    378 
    379 	if (t == UINT8_ERROR)
    380 		LOG("Unknown transformation: %s\n", buf);
    381 
    382 	return (oriented_cube_t){
    383 		.cube = transform(cube.cube, t),
    384 		.orientation = cube.orientation
    385 	};
    386 }
    387 
    388 STATIC_INLINE uint8_t
    389 inverse_trans(uint8_t t)
    390 {
    391 	return inverse_trans_table[t];
    392 }
    393 
    394 STATIC uint64_t
    395 symmetry_mask(cube_t cube)
    396 {
    397 	uint64_t t, ret;
    398 	cube_t transformed;
    399 
    400 	for (t = 0, ret = 0; t < NTRANS; t++) {
    401 		transformed = transform(cube, t);
    402 		ret |= ((uint64_t)equal(cube, transformed)) << t;
    403 	}
    404 
    405 	return ret;
    406 }