aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2025-08-06 16:34:21 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2025-08-06 16:52:12 +0200
commit57a7520545134ab95f7bb0397dcbe991c906a3e9 (patch)
tree689e20a92ec3830533d2fb868e5dc141dec45877
parenta5c9b857a346343443baf49679eebf12c18b4008 (diff)
downloadnissy-core-57a7520545134ab95f7bb0397dcbe991c906a3e9.tar.gz
nissy-core-57a7520545134ab95f7bb0397dcbe991c906a3e9.zip
Added HTR solver
-rw-r--r--src/arch/avx2.h24
-rw-r--r--src/arch/common.h39
-rw-r--r--src/arch/neon.h23
-rw-r--r--src/arch/portable.h16
-rw-r--r--src/core/constants.h4
-rw-r--r--src/solvers/coord/common.h24
-rw-r--r--src/solvers/coord/coord.h1
-rw-r--r--src/solvers/coord/cpepe.h15
-rw-r--r--src/solvers/coord/dr.h15
-rw-r--r--src/solvers/coord/dreo.h15
-rw-r--r--src/solvers/coord/drfinnoe.h15
-rw-r--r--src/solvers/coord/drslice.h15
-rw-r--r--src/solvers/coord/eo.h1
-rw-r--r--src/solvers/coord/htr.h125
-rw-r--r--src/solvers/coord/list.h1
-rw-r--r--src/solvers/coord/solve.h4
-rw-r--r--src/solvers/coord/types_macros.h1
-rw-r--r--test/083_invcoord_epudsep/00_all.in0
-rw-r--r--test/083_invcoord_epudsep/00_all.out1
-rw-r--r--test/083_invcoord_epudsep/invcoord_epudsep_tests.c32
-rw-r--r--tools/419_solvetest_HTR_from_UD/scrambles.h84
-rw-r--r--tools/419_solvetest_HTR_from_UD/solvetest.c9
22 files changed, 394 insertions, 70 deletions
diff --git a/src/arch/avx2.h b/src/arch/avx2.h
index 74aad53..1c7248b 100644
--- a/src/arch/avx2.h
+++ b/src/arch/avx2.h
@@ -437,5 +437,27 @@ is_eo_even(cube_t cube)
437 e = _mm256_slli_epi16(e, 7-EOSHIFT); 437 e = _mm256_slli_epi16(e, 7-EOSHIFT);
438 mask = _mm256_movemask_epi8(e); 438 mask = _mm256_movemask_epi8(e);
439 439
440 return popcount_u32(mask) % 2; 440 return popcount_u32(mask) % 2 == 0;
441}
442
443STATIC_INLINE uint64_t
444coord_epudsep(cube_t cube)
445{
446 uint8_t aux[32];
447
448 _mm256_storeu_si256((__m256i_u *)aux, cube);
449 return coord_epudsep_array(aux + 16);
450}
451
452STATIC_INLINE cube_t
453invcoord_epudsep(uint64_t i)
454{
455 cube_t cube, elow;
456 uint8_t e[32];
457
458 invcoord_epudsep_array(i, e+16);
459 elow = _mm256_load_si256((__m256i *)e);
460 cube = _mm256_set_epi64x(SOLVED_H, 0, 0, SOLVED_L);
461
462 return _mm256_or_si256(elow, cube);
441} 463}
diff --git a/src/arch/common.h b/src/arch/common.h
index d76b65f..f06f8d7 100644
--- a/src/arch/common.h
+++ b/src/arch/common.h
@@ -29,6 +29,8 @@ STATIC_INLINE uint64_t coord_cocsep(cube_t);
29STATIC_INLINE uint64_t coord_eo(cube_t); 29STATIC_INLINE uint64_t coord_eo(cube_t);
30STATIC_INLINE uint64_t coord_esep(cube_t); 30STATIC_INLINE uint64_t coord_esep(cube_t);
31STATIC_INLINE cube_t invcoord_esep(uint64_t); 31STATIC_INLINE cube_t invcoord_esep(uint64_t);
32STATIC_INLINE uint64_t coord_epudsep(cube_t);
33STATIC_INLINE cube_t invcoord_epudsep(uint64_t);
32 34
33STATIC_INLINE bool is_eo_even(cube_t); 35STATIC_INLINE bool is_eo_even(cube_t);
34 36
@@ -38,6 +40,8 @@ STATIC_INLINE void set_eo(cube_t [static 1], uint64_t);
38 40
39STATIC_INLINE void invcoord_esep_array(uint64_t, uint64_t, uint8_t[static 12]); 41STATIC_INLINE void invcoord_esep_array(uint64_t, uint64_t, uint8_t[static 12]);
40STATIC_INLINE cube_t invcoord_eoesep(uint64_t); 42STATIC_INLINE cube_t invcoord_eoesep(uint64_t);
43STATIC_INLINE uint64_t coord_epudsep_array(const uint8_t [8]);
44STATIC_INLINE void invcoord_epudsep_array(uint64_t, uint8_t [8]);
41 45
42STATIC_INLINE uint64_t coord_cp(cube_t); 46STATIC_INLINE uint64_t coord_cp(cube_t);
43STATIC_INLINE cube_t invcoord_cp(uint64_t); 47STATIC_INLINE cube_t invcoord_cp(uint64_t);
@@ -85,3 +89,38 @@ invcoord_eoesep(uint64_t i)
85 89
86 return c; 90 return c;
87} 91}
92
93STATIC_INLINE uint64_t
94coord_epudsep_array(const uint8_t e[8])
95{
96 uint8_t i, k, is;
97 uint64_t ret;
98
99 ret = 0;
100 k = 4;
101 for (i = 0; i < 8; i++) {
102 is = (e[i] & UINT8_C(4)) >> UINT8_C(2);
103 ret += is * binomial[7-i][k];
104 k -= is;
105 }
106
107 return ret;
108}
109
110STATIC_INLINE void
111invcoord_epudsep_array(uint64_t c, uint8_t ret[8])
112{
113 uint8_t i, k, is, x, y;
114
115 k = 4;
116 x = 0;
117 y = 4;
118 for (i = 0; i < 8; i++) {
119 is = c >= binomial[7-i][k];
120 ret[i] = is*y + (1-is)*x;
121 y += is;
122 x += 1-is;
123 c -= is * binomial[7-i][k];
124 k -= is;
125 }
126}
diff --git a/src/arch/neon.h b/src/arch/neon.h
index 2c35c58..9871125 100644
--- a/src/arch/neon.h
+++ b/src/arch/neon.h
@@ -453,7 +453,7 @@ invcoord_cp(uint64_t i)
453{ 453{
454 return (cube_t) { 454 return (cube_t) {
455 .corner = indextoperm_8x8(i), 455 .corner = indextoperm_8x8(i),
456 .edge = vcombine_u8(vld1_u8(SOLVED_L), vld1_u8(SOLVED_H)) 456 .edge = vcombine_u8(vld1_u8(SOLVED_L), vld1_u8(SOLVED_H))
457 }; 457 };
458} 458}
459 459
@@ -515,3 +515,24 @@ is_eo_even(cube_t cube)
515 515
516 return count % 2 == 0; 516 return count % 2 == 0;
517} 517}
518
519STATIC_INLINE uint64_t
520coord_epudsep(cube_t cube)
521{
522 uint8_t e[8];
523
524 vst1_u8(e, vget_low_u8(cube.edge));
525 return coord_epudsep_array(e);
526}
527
528STATIC_INLINE cube_t
529invcoord_epudsep(uint64_t i)
530{
531 uint8_t e[8];
532
533 invcoord_epudsep_array(i, e);
534 return (cube_t) {
535 .corner = vld1_u8(SOLVED_L),
536 .edge = vcombine_u8(vld1_u8(e), vld1_u8(SOLVED_H))
537 };
538}
diff --git a/src/arch/portable.h b/src/arch/portable.h
index d673f15..c7f2de0 100644
--- a/src/arch/portable.h
+++ b/src/arch/portable.h
@@ -367,3 +367,19 @@ is_eo_even(cube_t cube)
367 367
368 return count % 2 == 0; 368 return count % 2 == 0;
369} 369}
370
371STATIC_INLINE uint64_t
372coord_epudsep(cube_t cube)
373{
374 return coord_epudsep_array(cube.edge);
375}
376
377STATIC_INLINE cube_t
378invcoord_epudsep(uint64_t c)
379{
380 cube_t ret;
381
382 ret = SOLVED_CUBE;
383 invcoord_epudsep_array(c, ret.edge);
384 return ret;
385}
diff --git a/src/core/constants.h b/src/core/constants.h
index 3e6941d..26f6916 100644
--- a/src/core/constants.h
+++ b/src/core/constants.h
@@ -360,6 +360,10 @@
360 MM18_FACE(MOVE_U) | MM18_FACE(MOVE_D) |\ 360 MM18_FACE(MOVE_U) | MM18_FACE(MOVE_D) |\
361 MM_SINGLE(MOVE_R2) | MM_SINGLE(MOVE_L2) |\ 361 MM_SINGLE(MOVE_R2) | MM_SINGLE(MOVE_L2) |\
362 MM_SINGLE(MOVE_F2) | MM_SINGLE(MOVE_B2)) 362 MM_SINGLE(MOVE_F2) | MM_SINGLE(MOVE_B2))
363#define MM18_DRHTR (\
364 MM18_FACE(MOVE_U) | MM_SINGLE(MOVE_D) | MM_SINGLE(MOVE_D3) |\
365 MM_SINGLE(MOVE_R2) | MM_SINGLE(MOVE_L2) |\
366 MM_SINGLE(MOVE_F2) | MM_SINGLE(MOVE_B2))
363#define MM18_DR_NOD (MM18_DR & ~MM18_FACE(MOVE_D)) 367#define MM18_DR_NOD (MM18_DR & ~MM18_FACE(MOVE_D))
364#define MM18_HTR (MM18_ALLMOVES & ~MM18_NOHALFTURNS) 368#define MM18_HTR (MM18_ALLMOVES & ~MM18_NOHALFTURNS)
365 369
diff --git a/src/solvers/coord/common.h b/src/solvers/coord/common.h
index 5b5f57b..5f2435d 100644
--- a/src/solvers/coord/common.h
+++ b/src/solvers/coord/common.h
@@ -12,6 +12,9 @@ STATIC bool coord_can_switch(const coord_t [static 1], const unsigned char *,
12STATIC bool coord_is_solved( 12STATIC bool coord_is_solved(
13 const coord_t [static 1], uint64_t, const unsigned char *); 13 const coord_t [static 1], uint64_t, const unsigned char *);
14 14
15STATIC cube_t coordinate_merge_ce(cube_t, cube_t);
16STATIC cube_t coordinate_merge_ec(cube_t, cube_t);
17
15STATIC uint64_t 18STATIC uint64_t
16coord_coord_generic( 19coord_coord_generic(
17 const coord_t coord[static 1], 20 const coord_t coord[static 1],
@@ -19,13 +22,11 @@ coord_coord_generic(
19 const unsigned char *data 22 const unsigned char *data
20) 23)
21{ 24{
22 const unsigned char *datanoinfo;
23 const uint32_t *data32; 25 const uint32_t *data32;
24 uint32_t d; 26 uint32_t d;
25 cube_t tr; 27 cube_t tr;
26 28
27 datanoinfo = data + INFOSIZE; 29 data32 = (const uint32_t *)(data + INFOSIZE);
28 data32 = (const uint32_t *)datanoinfo;
29 d = data32[coord->sym.coord(c)]; 30 d = data32[coord->sym.coord(c)];
30 tr = transform(c, COORD_TTREP(d)); 31 tr = transform(c, COORD_TTREP(d));
31 32
@@ -197,3 +198,20 @@ coord_is_solved(
197{ 198{
198 return coord->is_solved == NULL ? i == 0 : coord->is_solved(i, data); 199 return coord->is_solved == NULL ? i == 0 : coord->is_solved(i, data);
199} 200}
201
202STATIC cube_t
203coordinate_merge_ce(cube_t corners, cube_t edges)
204{
205 cube_t merged;
206
207 merged = corners;
208 copy_edges(&merged, edges);
209
210 return merged;
211}
212
213STATIC cube_t
214coordinate_merge_ec(cube_t edges, cube_t corners)
215{
216 return coordinate_merge_ce(corners, edges);
217}
diff --git a/src/solvers/coord/coord.h b/src/solvers/coord/coord.h
index beb1b6a..db40239 100644
--- a/src/solvers/coord/coord.h
+++ b/src/solvers/coord/coord.h
@@ -7,6 +7,7 @@
7#include "drslice.h" 7#include "drslice.h"
8#include "cpepe.h" 8#include "cpepe.h"
9#include "drfin.h" 9#include "drfin.h"
10#include "htr.h"
10#include "list.h" 11#include "list.h"
11#include "utils.h" 12#include "utils.h"
12#include "gendata.h" 13#include "gendata.h"
diff --git a/src/solvers/coord/cpepe.h b/src/solvers/coord/cpepe.h
index 9c9bffc..7035400 100644
--- a/src/solvers/coord/cpepe.h
+++ b/src/solvers/coord/cpepe.h
@@ -1,4 +1,3 @@
1STATIC cube_t coordinate_cpepe_merge(const cube_t, const cube_t);
2STATIC uint64_t coordinate_cpepe_coord(const cube_t, const unsigned char *); 1STATIC uint64_t coordinate_cpepe_coord(const cube_t, const unsigned char *);
3STATIC cube_t coordinate_cpepe_cube(uint64_t, const unsigned char *); 2STATIC cube_t coordinate_cpepe_cube(uint64_t, const unsigned char *);
4STATIC bool coordinate_cpepe_isnasty(uint64_t, const unsigned char *); 3STATIC bool coordinate_cpepe_isnasty(uint64_t, const unsigned char *);
@@ -15,6 +14,7 @@ STATIC coord_t coordinate_cpepe = {
15 .moves_mask_gendata = MM18_DR, 14 .moves_mask_gendata = MM18_DR,
16 .moves_mask_solve = MM18_DR, 15 .moves_mask_solve = MM18_DR,
17 .is_admissible = &solution_always_valid, 16 .is_admissible = &solution_always_valid,
17 .solution_prune = NULL,
18 .is_solvable = &is_drfinnoe_solvable, 18 .is_solvable = &is_drfinnoe_solvable,
19 .is_solved = NULL, 19 .is_solved = NULL,
20 .allow_niss = false, 20 .allow_niss = false,
@@ -44,21 +44,10 @@ STATIC coord_t coordinate_cpepe = {
44 .max2 = FACT_4, 44 .max2 = FACT_4,
45 .coord2 = &coord_epe, 45 .coord2 = &coord_epe,
46 .cube2 = &invcoord_epe, 46 .cube2 = &invcoord_epe,
47 .merge = &coordinate_cpepe_merge, 47 .merge = &coordinate_merge_ce,
48 }, 48 },
49}; 49};
50 50
51STATIC cube_t
52coordinate_cpepe_merge(const cube_t c1, const cube_t c2)
53{
54 cube_t merged;
55
56 merged = c1;
57 copy_edges(&merged, c2);
58
59 return merged;
60}
61
62STATIC uint64_t 51STATIC uint64_t
63coordinate_cpepe_coord(const cube_t cube, const unsigned char *data) 52coordinate_cpepe_coord(const cube_t cube, const unsigned char *data)
64{ 53{
diff --git a/src/solvers/coord/dr.h b/src/solvers/coord/dr.h
index 03473df..8100910 100644
--- a/src/solvers/coord/dr.h
+++ b/src/solvers/coord/dr.h
@@ -3,7 +3,6 @@
3 3
4STATIC uint64_t coord_dreoesep_nosym(cube_t); 4STATIC uint64_t coord_dreoesep_nosym(cube_t);
5STATIC cube_t invcoord_dreoesep_nosym(uint64_t); 5STATIC cube_t invcoord_dreoesep_nosym(uint64_t);
6STATIC cube_t coordinate_dr_merge(cube_t, cube_t);
7 6
8STATIC uint64_t coordinate_dr_coord(cube_t, const unsigned char *); 7STATIC uint64_t coordinate_dr_coord(cube_t, const unsigned char *);
9STATIC cube_t coordinate_dr_cube(uint64_t, const unsigned char *); 8STATIC cube_t coordinate_dr_cube(uint64_t, const unsigned char *);
@@ -23,6 +22,7 @@ STATIC coord_t coordinate_dr = {
23 .moves_mask_gendata = MM18_ALLMOVES, 22 .moves_mask_gendata = MM18_ALLMOVES,
24 .moves_mask_solve = MM18_ALLMOVES, 23 .moves_mask_solve = MM18_ALLMOVES,
25 .is_admissible = &solution_lastqt_cw, 24 .is_admissible = &solution_lastqt_cw,
25 .solution_prune = NULL,
26 .is_solvable = &is_eoco_solvable, 26 .is_solvable = &is_eoco_solvable,
27 .is_solved = NULL, 27 .is_solved = NULL,
28 .allow_niss = true, 28 .allow_niss = true,
@@ -50,7 +50,7 @@ STATIC coord_t coordinate_dr = {
50 .max2 = POW_3_7, 50 .max2 = POW_3_7,
51 .coord2 = &coord_co, 51 .coord2 = &coord_co,
52 .cube2 = &invcoord_co, 52 .cube2 = &invcoord_co,
53 .merge = &coordinate_dr_merge, 53 .merge = &coordinate_merge_ec,
54 }, 54 },
55}; 55};
56 56
@@ -79,17 +79,6 @@ invcoord_dreoesep_nosym(uint64_t coord)
79 return cube; 79 return cube;
80} 80}
81 81
82STATIC cube_t
83coordinate_dr_merge(cube_t c1, cube_t c2)
84{
85 cube_t merged;
86
87 merged = c1;
88 copy_corners(&merged, c2);
89
90 return merged;
91}
92
93STATIC uint64_t 82STATIC uint64_t
94coordinate_dr_coord(cube_t cube, const unsigned char *data) 83coordinate_dr_coord(cube_t cube, const unsigned char *data)
95{ 84{
diff --git a/src/solvers/coord/dreo.h b/src/solvers/coord/dreo.h
index f563129..c5cacac 100644
--- a/src/solvers/coord/dreo.h
+++ b/src/solvers/coord/dreo.h
@@ -2,7 +2,6 @@
2 2
3STATIC uint64_t coord_dresep_nosym(cube_t); 3STATIC uint64_t coord_dresep_nosym(cube_t);
4STATIC cube_t invcoord_dresep_nosym(uint64_t); 4STATIC cube_t invcoord_dresep_nosym(uint64_t);
5STATIC cube_t coordinate_dreo_merge(cube_t, cube_t);
6 5
7STATIC uint64_t coordinate_dreo_coord(cube_t, const unsigned char *); 6STATIC uint64_t coordinate_dreo_coord(cube_t, const unsigned char *);
8STATIC cube_t coordinate_dreo_cube(uint64_t, const unsigned char *); 7STATIC cube_t coordinate_dreo_cube(uint64_t, const unsigned char *);
@@ -22,6 +21,7 @@ STATIC coord_t coordinate_dreo = {
22 .moves_mask_gendata = MM18_EO, 21 .moves_mask_gendata = MM18_EO,
23 .moves_mask_solve = MM18_EO, 22 .moves_mask_solve = MM18_EO,
24 .is_admissible = &solution_lastqt_cw, 23 .is_admissible = &solution_lastqt_cw,
24 .solution_prune = NULL,
25 .is_solvable = &is_dreo_solvable, 25 .is_solvable = &is_dreo_solvable,
26 .is_solved = NULL, 26 .is_solved = NULL,
27 .allow_niss = true, 27 .allow_niss = true,
@@ -47,7 +47,7 @@ STATIC coord_t coordinate_dreo = {
47 .max2 = POW_3_7, 47 .max2 = POW_3_7,
48 .coord2 = &coord_co, 48 .coord2 = &coord_co,
49 .cube2 = &invcoord_co, 49 .cube2 = &invcoord_co,
50 .merge = &coordinate_dreo_merge, 50 .merge = &coordinate_merge_ec,
51 }, 51 },
52}; 52};
53 53
@@ -63,17 +63,6 @@ invcoord_dresep_nosym(uint64_t coord)
63 return invcoord_esep(coord * COMB_8_4); 63 return invcoord_esep(coord * COMB_8_4);
64} 64}
65 65
66STATIC cube_t
67coordinate_dreo_merge(cube_t c1, cube_t c2)
68{
69 cube_t merged;
70
71 merged = c1;
72 copy_corners(&merged, c2);
73
74 return merged;
75}
76
77STATIC uint64_t 66STATIC uint64_t
78coordinate_dreo_coord(cube_t cube, const unsigned char *data) 67coordinate_dreo_coord(cube_t cube, const unsigned char *data)
79{ 68{
diff --git a/src/solvers/coord/drfinnoe.h b/src/solvers/coord/drfinnoe.h
index 4370779..63f4edf 100644
--- a/src/solvers/coord/drfinnoe.h
+++ b/src/solvers/coord/drfinnoe.h
@@ -13,7 +13,6 @@ In the worst case, it is a bug to be fixed, but I find it unlikely.
13 13
14#define CLASSES_CP_16 2768 14#define CLASSES_CP_16 2768
15 15
16STATIC cube_t coordinate_drfinnoe_merge(cube_t, cube_t);
17STATIC uint64_t coordinate_drfinnoe_coord(cube_t, const unsigned char *); 16STATIC uint64_t coordinate_drfinnoe_coord(cube_t, const unsigned char *);
18STATIC cube_t coordinate_drfinnoe_cube(uint64_t, const unsigned char *); 17STATIC cube_t coordinate_drfinnoe_cube(uint64_t, const unsigned char *);
19STATIC bool coordinate_drfinnoe_isnasty(uint64_t, const unsigned char *); 18STATIC bool coordinate_drfinnoe_isnasty(uint64_t, const unsigned char *);
@@ -32,6 +31,7 @@ STATIC coord_t coordinate_drfinnoe = {
32 .moves_mask_gendata = MM18_DR, 31 .moves_mask_gendata = MM18_DR,
33 .moves_mask_solve = MM18_DR, 32 .moves_mask_solve = MM18_DR,
34 .is_admissible = &solution_always_valid, 33 .is_admissible = &solution_always_valid,
34 .solution_prune = NULL,
35 .is_solvable = &is_drfinnoe_solvable, 35 .is_solvable = &is_drfinnoe_solvable,
36 .is_solved = NULL, 36 .is_solved = NULL,
37 .allow_niss = false, 37 .allow_niss = false,
@@ -62,21 +62,10 @@ STATIC coord_t coordinate_drfinnoe = {
62 .max2 = FACT_8, 62 .max2 = FACT_8,
63 .coord2 = &coord_epud, 63 .coord2 = &coord_epud,
64 .cube2 = &invcoord_epud, 64 .cube2 = &invcoord_epud,
65 .merge = &coordinate_drfinnoe_merge, 65 .merge = &coordinate_merge_ce,
66 }, 66 },
67}; 67};
68 68
69STATIC cube_t
70coordinate_drfinnoe_merge(cube_t c1, cube_t c2)
71{
72 cube_t merged;
73
74 merged = c1;
75 copy_edges(&merged, c2);
76
77 return merged;
78}
79
80STATIC uint64_t 69STATIC uint64_t
81coordinate_drfinnoe_coord(cube_t cube, const unsigned char *data) 70coordinate_drfinnoe_coord(cube_t cube, const unsigned char *data)
82{ 71{
diff --git a/src/solvers/coord/drslice.h b/src/solvers/coord/drslice.h
index c9403f8..42699f8 100644
--- a/src/solvers/coord/drslice.h
+++ b/src/solvers/coord/drslice.h
@@ -5,7 +5,6 @@ much of the code of DRFINNOE. We could make the pruning table 4x smaller
5if we reduced the coordinate by rotations. TODO. 5if we reduced the coordinate by rotations. TODO.
6*/ 6*/
7 7
8STATIC cube_t coordinate_drslice_merge(cube_t, cube_t);
9STATIC uint64_t coordinate_drslice_coord(cube_t, const unsigned char *); 8STATIC uint64_t coordinate_drslice_coord(cube_t, const unsigned char *);
10STATIC cube_t coordinate_drslice_cube(uint64_t, const unsigned char *); 9STATIC cube_t coordinate_drslice_cube(uint64_t, const unsigned char *);
11STATIC bool coordinate_drslice_isnasty(uint64_t, const unsigned char *); 10STATIC bool coordinate_drslice_isnasty(uint64_t, const unsigned char *);
@@ -24,6 +23,7 @@ STATIC coord_t coordinate_drslice = {
24 .moves_mask_gendata = MM18_DR, 23 .moves_mask_gendata = MM18_DR,
25 .moves_mask_solve = MM18_DR_NOD, 24 .moves_mask_solve = MM18_DR_NOD,
26 .is_admissible = &solution_always_valid, 25 .is_admissible = &solution_always_valid,
26 .solution_prune = NULL,
27 .is_solvable = &is_drslice_solvable, 27 .is_solvable = &is_drslice_solvable,
28 .is_solved = &is_drslice_solved, 28 .is_solved = &is_drslice_solved,
29 .allow_niss = false, 29 .allow_niss = false,
@@ -54,21 +54,10 @@ STATIC coord_t coordinate_drslice = {
54 .max2 = FACT_8, 54 .max2 = FACT_8,
55 .coord2 = &coord_epud, 55 .coord2 = &coord_epud,
56 .cube2 = &invcoord_epud, 56 .cube2 = &invcoord_epud,
57 .merge = &coordinate_drslice_merge, 57 .merge = &coordinate_merge_ce,
58 }, 58 },
59}; 59};
60 60
61STATIC cube_t
62coordinate_drslice_merge(cube_t c1, cube_t c2)
63{
64 cube_t merged;
65
66 merged = c1;
67 copy_edges(&merged, c2);
68
69 return merged;
70}
71
72STATIC uint64_t 61STATIC uint64_t
73coordinate_drslice_coord(cube_t cube, const unsigned char *data) 62coordinate_drslice_coord(cube_t cube, const unsigned char *data)
74{ 63{
diff --git a/src/solvers/coord/eo.h b/src/solvers/coord/eo.h
index 5c823a1..42196af 100644
--- a/src/solvers/coord/eo.h
+++ b/src/solvers/coord/eo.h
@@ -14,6 +14,7 @@ STATIC coord_t coordinate_eo = {
14 .moves_mask_gendata = MM18_ALLMOVES, 14 .moves_mask_gendata = MM18_ALLMOVES,
15 .moves_mask_solve = MM18_ALLMOVES, 15 .moves_mask_solve = MM18_ALLMOVES,
16 .is_admissible = &solution_lastqt_cw, 16 .is_admissible = &solution_lastqt_cw,
17 .solution_prune = NULL,
17 .is_solvable = &is_eo_even, 18 .is_solvable = &is_eo_even,
18 .is_solved = NULL, 19 .is_solved = NULL,
19 .allow_niss = true, 20 .allow_niss = true,
diff --git a/src/solvers/coord/htr.h b/src/solvers/coord/htr.h
new file mode 100644
index 0000000..cfd451b
--- /dev/null
+++ b/src/solvers/coord/htr.h
@@ -0,0 +1,125 @@
1STATIC uint64_t coordinate_htr_coord(cube_t, const unsigned char *);
2STATIC cube_t coordinate_htr_cube(uint64_t, const unsigned char *);
3STATIC bool coordinate_htr_isnasty(uint64_t, const unsigned char *);
4STATIC size_t coordinate_htr_gendata(unsigned char *);
5
6STATIC bool htr_checkmoves(bool *, uint8_t, const uint8_t *);
7STATIC bool htr_solution_prune(const solution_moves_t [static 1]);
8STATIC bool is_cp_htr(uint64_t, const unsigned char *);
9
10STATIC coord_t coordinate_htr = {
11 .name = "HTR",
12 .coord = &coordinate_htr_coord,
13 .cube = &coordinate_htr_cube,
14 .isnasty = &coordinate_htr_isnasty,
15 .gendata = coordinate_htr_gendata,
16 .max = CLASSES_CP_16 * COMB_8_4,
17 .trans_mask = TM_UDFIX,
18 .moves_mask_gendata = MM18_DR,
19 .moves_mask_solve = MM18_DRHTR,
20 .is_admissible = &solution_lastqt_cw,
21 .solution_prune = &htr_solution_prune,
22 .is_solvable = &is_drfinnoe_solvable,
23 .is_solved = &is_cp_htr,
24 .allow_niss = true,
25 .pruning_distribution = {
26 [0] = 22,
27 [1] = 18,
28 [2] = 86,
29 [3] = 268,
30 [4] = 920,
31 [5] = 4042,
32 [6] = 12716,
33 [7] = 24852,
34 [8] = 33116,
35 [9] = 45032,
36 [10] = 47144,
37 [11] = 21676,
38 [12] = 3692,
39 [13] = 176
40 },
41 .pruning_max = 13,
42 .sym = {
43 .classes = CLASSES_CP_16,
44 .max = FACT_8,
45 .coord = &coord_cp,
46 .cube = &invcoord_cp,
47 .max2 = COMB_8_4,
48 .coord2 = &coord_epudsep,
49 .cube2 = &invcoord_epudsep,
50 .merge = &coordinate_merge_ce,
51 },
52};
53
54STATIC uint64_t
55coordinate_htr_coord(cube_t cube, const unsigned char *data)
56{
57 return coord_coord_generic(&coordinate_htr, cube, data);
58}
59
60STATIC cube_t
61coordinate_htr_cube(uint64_t i, const unsigned char *data)
62{
63 return coord_cube_generic(&coordinate_htr, i, data);
64}
65
66STATIC bool
67coordinate_htr_isnasty(uint64_t i, const unsigned char *data)
68{
69 return coord_isnasty_generic(&coordinate_htr, i, data);
70}
71
72STATIC size_t
73coordinate_htr_gendata(unsigned char *data)
74{
75 return coord_gendata_generic(&coordinate_htr, data);
76}
77
78STATIC bool
79htr_checkmoves(bool *f, uint8_t n, const uint8_t *moves)
80{
81 uint8_t i;
82 bool is_d, is_u;
83
84 for (i = 0; i < n; i++) {
85 is_d = moves[i] == MOVE_D || moves[i] == MOVE_D3;
86 is_u = moves[i] == MOVE_U || moves[i] == MOVE_U3;
87 if (is_d && *f)
88 return true;
89 *f = *f || is_d || is_u;
90
91 if (i < n-1 && moveaxis(moves[i]) == 0 &&
92 parallel(moves[i], moves[i+1]))
93 return true;
94 }
95
96 return false;
97}
98
99STATIC bool
100htr_solution_prune(const solution_moves_t s[static 1])
101{
102 bool f;
103
104 f = false;
105
106 return htr_checkmoves(&f, s->nmoves, s->moves) ||
107 htr_checkmoves(&f, s->npremoves, s->premoves);
108}
109
110STATIC bool
111is_cp_htr(uint64_t i, const unsigned char *data)
112{
113 static uint8_t is_cp16_htr_table[DIV_ROUND_UP(CLASSES_CP_16, 8)] = {
114 [0] = 81, [7] = 144, [8] = 16, [25] = 130, [26] = 34,
115 [37] = 64, [38] = 48, [39] = 8, [212] = 20, [226] = 32,
116 [227] = 2, [298] = 160, [300] = 128, [301] = 1
117 };
118
119 uint64_t e, c;
120
121 e = i % COMB_8_4;
122 c = i / COMB_8_4;
123
124 return e == 0 && is_cp16_htr_table[c / 8] & (UINT8_C(1) << (c % 8));
125}
diff --git a/src/solvers/coord/list.h b/src/solvers/coord/list.h
index 7bc8041..9b59969 100644
--- a/src/solvers/coord/list.h
+++ b/src/solvers/coord/list.h
@@ -5,6 +5,7 @@ coord_t *all_coordinates[] = {
5 &coordinate_drfinnoe, 5 &coordinate_drfinnoe,
6 &coordinate_drslice, 6 &coordinate_drslice,
7 &coordinate_cpepe, 7 &coordinate_cpepe,
8 &coordinate_htr,
8 NULL 9 NULL
9}; 10};
10 11
diff --git a/src/solvers/coord/solve.h b/src/solvers/coord/solve.h
index 72bc064..54309b1 100644
--- a/src/solvers/coord/solve.h
+++ b/src/solvers/coord/solve.h
@@ -155,6 +155,10 @@ solve_coord_dfs(dfsarg_solve_coord_t arg[static 1])
155 int64_t n, ret; 155 int64_t n, ret;
156 cube_t backup_cube, backup_inverse; 156 cube_t backup_cube, backup_inverse;
157 157
158 if (arg->coord->solution_prune != NULL &&
159 arg->coord->solution_prune(arg->solution_moves))
160 return 0;
161
158 coord = arg->coord->coord(arg->cube, arg->coord_data); 162 coord = arg->coord->coord(arg->cube, arg->coord_data);
159 if (coord_is_solved(arg->coord, coord, arg->coord_data)) { 163 if (coord_is_solved(arg->coord, coord, arg->coord_data)) {
160 if (!coord_solution_admissible(arg)) 164 if (!coord_solution_admissible(arg))
diff --git a/src/solvers/coord/types_macros.h b/src/solvers/coord/types_macros.h
index 73484ba..98f9822 100644
--- a/src/solvers/coord/types_macros.h
+++ b/src/solvers/coord/types_macros.h
@@ -28,6 +28,7 @@ typedef struct {
28 uint64_t moves_mask_solve; 28 uint64_t moves_mask_solve;
29 uint64_t trans_mask; 29 uint64_t trans_mask;
30 bool (*is_admissible)(const solution_moves_t[static 1]); 30 bool (*is_admissible)(const solution_moves_t[static 1]);
31 bool (*solution_prune)(const solution_moves_t[static 1]);
31 bool (*is_solvable)(cube_t); 32 bool (*is_solvable)(cube_t);
32 bool (*is_solved)(uint64_t, const unsigned char *); 33 bool (*is_solved)(uint64_t, const unsigned char *);
33 uint64_t pruning_distribution[INFO_DISTRIBUTION_LEN]; 34 uint64_t pruning_distribution[INFO_DISTRIBUTION_LEN];
diff --git a/test/083_invcoord_epudsep/00_all.in b/test/083_invcoord_epudsep/00_all.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/083_invcoord_epudsep/00_all.in
diff --git a/test/083_invcoord_epudsep/00_all.out b/test/083_invcoord_epudsep/00_all.out
new file mode 100644
index 0000000..d6109db
--- /dev/null
+++ b/test/083_invcoord_epudsep/00_all.out
@@ -0,0 +1 @@
All good
diff --git a/test/083_invcoord_epudsep/invcoord_epudsep_tests.c b/test/083_invcoord_epudsep/invcoord_epudsep_tests.c
new file mode 100644
index 0000000..709e5d8
--- /dev/null
+++ b/test/083_invcoord_epudsep/invcoord_epudsep_tests.c
@@ -0,0 +1,32 @@
1#include "../test.h"
2
3#define COMB_8_4 70
4
5uint64_t coord_epudsep(cube_t);
6cube_t invcoord_epudsep(uint64_t);
7
8void run(void) {
9 oriented_cube_t cube;
10 uint64_t coord, coord2;
11
12 cube.orientation = 0;
13
14 /* Test all possible values for CP coordinate */
15 for (coord = 0; coord < COMB_8_4; coord++) {
16 cube.cube = invcoord_epudsep(coord);
17
18 if (!isconsistent(cube)) {
19 printf("Not consistent\n");
20 return;
21 }
22
23 coord2 = coord_epudsep(cube.cube);
24 if (coord != coord2) {
25 printf("Error: invcoord of %" PRIu64
26 " returns %" PRIu64 "\n", coord, coord2);
27 return;
28 }
29 }
30
31 printf("All good\n");
32}
diff --git a/tools/419_solvetest_HTR_from_UD/scrambles.h b/tools/419_solvetest_HTR_from_UD/scrambles.h
new file mode 100644
index 0000000..749da60
--- /dev/null
+++ b/tools/419_solvetest_HTR_from_UD/scrambles.h
@@ -0,0 +1,84 @@
1struct {
2 char *scramble;
3 char *solutions;
4} s[] = {
5[0] = {
6 .scramble = "U F2 U' R2 U L2 B2 L2 U D2 R2 L2 F2",
7 .solutions =
8 "(U F2 R2 B2 R2 U)\n"
9 "(U F2 L2 B2 L2 U)\n"
10 "(D R2 F2 R2 B2 U)\n"
11 "(D R2 B2 R2 F2 U)\n"
12},
13[1] = {
14 .scramble = "U L2 F2 U F2 U' D' L2 B2 U F2 D' R2 U'",
15 .solutions =
16 "(U F2 U F2 U' F2 U L2 U)\n"
17 "(U F2 U' F2 U L2 U' F2 U)\n"
18 "U R2 U L2 U (U L2 F2 U)\n"
19 "D B2 U F2 U (U R2 B2 U)\n"
20 "R2 U (U F2 U' F2 U L2 U)\n"
21 "R2 U (U' F2 U L2 U' F2 U)\n"
22},
23[2] = {
24 .scramble = "R2 L2 U2 B2 L2 U' R2 U F2 D R2 D' B2",
25 .solutions =
26 "B2 U2 R2 U F2 U\n"
27},
28[3] = {
29 .scramble = "R2 D2 R2 F2 U L2 B2 D L2 F2 D L2",
30 .solutions =
31 "R2 D' B2 U R2 U\n"
32 "(F2 U' F2 U F2 U)\n"
33},
34[4] = {
35 .scramble = "D F2 D F2 U' F2 B2 L2 U' D2 L2",
36 .solutions =
37 "(D F2 U L2 U' F2 U)\n"
38 "(D' B2 U' B2 U R2 U)\n"
39 "L2 U (U L2 U B2 U)\n"
40},
41[5] = {
42 .scramble = "R2 B2 R2 L2 U B2 D' L2 D F2 D' B2 D' L2 U",
43 .solutions =
44 "U R2 U' F2 U (U B2 U' F2 U)\n"
45 "F2 D B2 U L2 U2 B2 U (B2 U)\n"
46 "F2 D B2 U' B2 U2 L2 U (B2 U)\n"
47 "F2 D F2 U F2 U2 L2 U (B2 U)\n"
48 "F2 D F2 U' L2 U2 F2 U (B2 U)\n"
49},
50[6] = {
51 .scramble = "F2 U2 B2 R2 D' R2 U2 L2 B2 L2 D R2 D",
52 .solutions =
53 "(L2 U B2 L2 U F2 U)\n"
54 "U2 B2 U (L2 U L2 U)\n"
55},
56[7] = {
57 .scramble = "D2 B2 L2 F2 D B2 U B2 R2 B2 D2 R2 D'",
58 .solutions =
59 "U B2 U' L2 U\n"
60},
61[8] = {
62 .scramble = "U2 B2 U' R2 B2 U' R2 B2 U' B2 D' R2 D L2 D'",
63 .solutions =
64 "U R2 U' F2 U L2 U2 B2 U\n"
65 "U R2 U' F2 U' B2 U2 L2 U\n"
66 "U R2 U' B2 U F2 U2 L2 U\n"
67 "U R2 U' B2 U' L2 U2 F2 U\n"
68 "U2 L2 U (B2 U B2 U' L2 U)\n"
69 "U' L2 B2 U' R2 U (U2 F2 U)\n"
70 "D B2 U' L2 U (R2 U2 B2 U)\n"
71},
72[9] = {
73 .scramble = "B2 R2 U R2 U' L2 D F2 R2 U2 R2 L2 U",
74 .solutions =
75 "D B2 L2 U' L2 U R2 U\n"
76 "(L2 U R2 U' R2 U F2 U)\n"
77 "(L2 U' R2 U F2 U' R2 U)\n"
78 "D (B2 R2 U R2 U' L2 U)\n"
79 "B2 D (R2 U F2 U' L2 U)\n"
80},
81{
82 .scramble = "", /* End-of-list signal */
83}
84};
diff --git a/tools/419_solvetest_HTR_from_UD/solvetest.c b/tools/419_solvetest_HTR_from_UD/solvetest.c
new file mode 100644
index 0000000..b5de5f4
--- /dev/null
+++ b/tools/419_solvetest_HTR_from_UD/solvetest.c
@@ -0,0 +1,9 @@
1#define SOLVER "coord_HTR_UF"
2#define NISSFLAG NISSY_NISSFLAG_ALL
3#define MINMOVES 0
4#define MAXMOVES 20
5#define MAXSOLUTIONS 500
6#define OPTIMAL 0
7
8#include "scrambles.h"
9#include "../solvetest.h"

Generated with cgit - Back to sebastiano.tronto.net