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


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